Filename: Runtime//lexer_parser/upbeat.flex
Author: Adrian, Fan, Matt, Peyton
%%



%{
/* tokens */

%}
/* reg defs */
/* useful stuff */
delim =	[ \t\n\r]
ws =		{delim}+
letter =	[A-Za-z]
digit =	[0-9]

/* tokens */
id =		{letter}({letter}|{digit})*
int =		{digit}+
float =		{digit}+(\.{digit}+)
bool =		(TRUE|FALSE)
time =		@m{digit}+
string =	\"({letter}|{digit}|{ws})*\"

/* more useful stuff */
number =	{int}|{float}

%%

{ws}	{ /* do nothing */ }
;		{ printf ("\n"); /* end of statement */ }
{bool}	{ yylval = 1; printf("Ran across %s\n", yytext); return BOOL; }
TIME_SIGNATURE { yylval = 0; printf("Found a TIME_SIGNATURE\n"); return TIME_SIG
NATURE; }
TEMPO   { yylval = 0; printf("Found a TEMPO\n"); return TEMPO; }
{id}	{ yylval = (int) installID(); return ID; }
{int}	{ yylval = (int) installNum(); return INT; }
{float}	{ yylval = (int) installNum(); return FLOAT; }
{time}	{ yylval = 0; printf("Saw time %s\n", yytext); return TIME;}
{string}	{ yylval = 0; printf("Got a string! %s\n", yytext); return STRIN
G; }
"<"			{ yylval = LT_OP; return(LT_OP);}
">"			{ yylval = GT_OP; return(GT_OP);}
"<="		{ yylval = LE_OP; return(LE_OP);}
">="		{ yylval = GE_OP; return(GE_OP);}


/*


package edu.columbia.upbeat;

import java_cup.runtime.*;
import java.io.IOException;

// import edu.columbia.upbeat.UpbeatSym;
// import static edu.columbia.upbeat.UpbeatSym.*;

%%

%class UpbeatLex

%unicode
%line
%column

// %public
%final
// %abstract

// %cupsym UpbeatSym
// %cup
// %cupdebug

%init{
	// TODO: code that goes to constructor
%init}

%{
	private Symbol sym(int type)
	{
		return sym(type, yytext());
	}

	private Symbol sym(int type, Object value)
	{
		return new Symbol(type, yyline, yycolumn, value);
	}

	private void error()
	throws IOException
	{
		throw new IOException("illegal text at line = "+yyline+", column
 = "+yycolumn+", text = '"+yytext()+"'");
	}
%}

ANY			=	.

%%

{ANY}		{	return sym(ANY); }

*/




Filename: Runtime//src/upbeat/Conductor.java
Author: Matt
package upbeat;


import upbeat.types.Cue;

/**
 *
 * This is the abstract class of the Conductor.  The Conductor in the Upbeat pro
gram will create a new
 * class which derives from this one.  Functionality in this abstract class prov
ides an interface for
 * the {@link Manager} to use.  It also handles all input given to it by the Man
ager and puts it in an easy
 * to access format for the derived Conductor.
 * 
 * @author Matt
 */
abstract public class Conductor implements ConductorInterface{
	/**
	 * mMan is a member variable that is a pointer to the {@link Manager} wi
th which this Conductor interacts.
	 * This pointer is needed in order to do things like add {@link Cue}s to
 the score.
	 */
	private Manager mMan;
	
	/**
	 * This handles all the input that the Conductor object is given by the 
{@link Manager}.  It provides an
	 * easy interface that the Upbeat-programmer implemented version of Cond
uct() can use to get at the input.
	 */
	protected DataHandler input;
	
	//TODO Provide accessor methods to these member variables
	
	protected Conductor() {
		input = new DataHandler();
	}
	
	/**
	 * This should be the only constructor that ever gets used
	 * @param man	pointer to the {@link Manager} object that this Conducto
r will be interacting with.
	 */
	protected Conductor( Manager man ) {
		mMan = man;
		input = new DataHandler();
	}
	
	protected final void AddCueToScore( Cue c, int time ) {
		Cue newCue = c.clone();
		newCue.setTime(time);
		mMan.AddCueToScore( newCue );
	}
	
	/**
	 * Sets the manager pointer
	 * @param man	pointer to the {@link Manager} object that this Conducto
r will be interacting with.
	 */
	public final void SetManager( Manager man ){
		mMan = man;
	}
	
	/**
	 * Gets the Manager.
	 * @return	pointer to the {@link Manager} object used by this Condu
ctor
	 */
	protected final Manager GetManager() {
		return mMan;
	}
	
	/**
	 * This version of Conduct is called by the {@link Manager} at the very 
end of all the input.
	 * 
	 * @param currentMeasure	the current measure in the song.
	 * @param newData			the new data to be associated wi
th this measure.
	 * @param done				a boolean value saying whether o
r not we are finished processing input.
	 * 							If this is set t
o false, then call the other version of Conduct.
	 */
	public final void Conduct( int currentMeasure, double newData, boolean d
one) {
		input.SetMore( !done );
		Conduct( currentMeasure, newData );
	}
	
	/**
	 * Method called by the {@link Manager} to get the Conductor to generate
 some @{link Cue}s.
	 * 
	 * @param currentMeasure	the current measure of the song.
	 * @param newData			the new data to be associated wi
th this measure.
	 */
	public final void Conduct( int currentMeasure, double newData ) {
		input.FeedData( newData );
		Conduct(currentMeasure);
	}
	
	/**
	 * This will be the actual version of Conduct implemented by the Upbeat-
programmer.
	 * 
	 * @param currentMeasure	the current measure of the song.
	 */
	abstract protected void Conduct( int currentMeasure );
}



Filename: Runtime//src/upbeat/ConductorInterface.java
Author: Matt
package upbeat;

public interface ConductorInterface {
	
	public void SetManager(Manager man);

	/**
	 * This version of Conduct is called by the {@link Manager} at the very 
end
	 * of all the input.
	 * 
	 * @param currentMeasure
	 *            the current measure in the song.
	 * @param newData
	 *            the new data to be associated with this measure.
	 * @param done
	 *            a boolean value saying whether or not we are finished
	 *            processing input. If this is set to false, then call the o
ther
	 *            version of Conduct.
	 */
	public void Conduct(int currentMeasure, double newData, boolean done);

	/**
	 * Method called by the {@link Manager} to get the Conductor to generate
	 * some @{link Cue}s.
	 * 
	 * @param currentMeasure
	 *            the current measure of the song.
	 * @param newData
	 *            the new data to be associated with this measure.
	 */
	public void Conduct(int currentMeasure, double newData);
}




Filename: Runtime//src/upbeat/DataHandler.java
Author: Matt
package upbeat;

import java.util.Vector;

/**
 * 
 * This class handles the input for the {@link Conductor} class.  It stores the 
data and provides a simple interface
 * for the Upbeat-programmer implemented version of Conduct to access it with.
 * 
 * @author Matt
 *
 */
public class DataHandler {
	private boolean mMore;
	private Vector<Double> mData;
	
	/**
	 * Default constructor.  Initializes mMore to true.  Need to add in init
ialization of
	 * data structure to be used to keep track of data...
	 */
	DataHandler() {
		mMore = true;
		mData = new Vector<Double>();
		mData.add( new Double(0.0) );
	}
	
	/**
	 * Used by the {@link Conductor} to give data to the InputHandler. 
	 * @param newData	the new data to be kept track of.
	 */
	void FeedData( double newData ) {
		Double data = new Double(newData);
		mData.add( data );
	}
	
	/**
	 * Gives the most recent input value.
	 * @return	the most recent input value.
	 */
	public double CurrentValue() {
		return mData.lastElement().doubleValue();
	}
	
	/**
	 * Gives the input that was received at a particular time.  Might want t
o
	 * make this throw an exception if a time in the future is specified.
	 * @param time	when was the input received
	 * @return		the input at time.
	 * @throws Exception 
	 */
	public double ValueAt( int time ) throws Exception {
		if( time >= 0 && time < mData.size() ) {
			return mData.elementAt(time).doubleValue();
		}
		String err = String.format("Error: DataHandler.ValueAt(): time %
d is out of range!  Returning 0.0.", time);
		throw new IndexOutOfBoundsException(err);
	}
	
	/**
	 * Sets mMore.  If mMore == false, then that's the end of the song!
	 * @param more	The new value for mMore.
	 */
	void SetMore( boolean more ) {
		mMore = more;
	}
	
	/**
	 * Determines whether there will be more input forthcoming or not.
	 * @return	whether or not there will be more input forthcoming.
	 */
	public boolean GetMore() {
		return mMore;
	}
}




Filename: Runtime//src/upbeat/jmusiclib/JMusicWrapper.java
Author: Miles, Peyton, Matt
package upbeat.jmusiclib;

import upbeat.types.Measure;
import java.util.LinkedList;
import java.util.HashMap;
import java.util.Map;
import jm.music.data.*;
import jm.music.tools.Mod;
import jm.util.*;

import java.io.File;

/**
 * This is a wrapper for the JMusic library. It accepts a {@link Measure} of mus
ic at a time,
 * and uses JMusic to build up a midi file which is then written to disk. Curren
tly, it 
 * writes all output to "upbeat.mid".
 * 
 * @author Matt
 *
 */
public class JMusicWrapper implements JMusicWrapperInterface{
	
	/**
	 * A JMusic datatype used to build up and then output the music.
	 */
	private static Score mScore = new Score();
	private static Map <String, Score> mScores = new HashMap<String, Score>(
);
	private static int mCurrentMeasure = 1;
	private static int mTempo = 100;
	
	/**
	 * Used by the Manager class to pass a new measure of music to JMusic.  
At the moment, this should
	 * just be appended onto the end of a MIDI file.  Eventually, we'll want
 to add in another method
	 * for actually playing this stuff in real time.
	 * 
	 * @param newMeasure	This is a linked list containing a bunch of meas
ures.  The measures of music
	 * in newMeasure should be played <i>simultaneously</i>.  Thus, even tho
ugh there may be many {@link Measure}
	 * objects passed to AppendNextMeasure, they only actually produce one m
easure of music in the final song.
	 */
	public void AppendNextMeasure( LinkedList< Measure > newMeasure ) {
		
		// 1. step through list of measures
		// 2. extract appropriate measure from given filename
		// 3. build up JMusic Phrase
		// 4. append to mScore
		// 5. when finished, write to disk
		
		int timesig_num = 4;
		int timesig_den = 4;
		
		for (Measure measure : newMeasure) {
			
			// if this is a REST measure, add in silence and continu
e
			if (measure.getMidiName() == "REST") {
				continue;
			}

			Part newPart = new Part();
			
			/* 
			 * if this is the first time encountering this MIDI file
,
			 * initialize it and add it to the map
			 */
			if (!mScores.containsKey(measure.getMidiName())) {
				
				// Parse in the MIDI file
				Score score = new Score(measure.toString());
				Read.midi(score, measure.getMidiName());
				
				// make sure there is valid data
				if (score.getPart(0) == null) {
					throw new Error("Bad MIDI file passed in
: " + measure.toString());
				}
				
				// add the Score to our map
				mScores.put(measure.getMidiName(), score);
				
			}		
			
			Score score = mScores.get(measure.getMidiName());
			Part oldPart = score.getPart(0);
			
			// filter out phrases to the relevant measure
			// for (int i = 0; i < oldPart.getPhraseArray().length; 
i++) {
			for (Phrase p : oldPart.getPhraseArray()) {
				
				// ends too early, ignore
				if (p.getEndTime() < timesig_den * (measure.getM
easure() - 1)) {
					continue;
			    // starts too late, we can stop looking
				} else if (p.getStartTime() > timesig_den * meas
ure.getMeasure()) {
					continue;
				}

				// add all valid notes from the phrase
				Phrase newPhrase = new Phrase();
				jm.music.data.Note[] notes = p.getNoteArray();
				double duration = p.getStartTime();
				int note = 0;
				
				for (; note < notes.length && duration < (measur
e.getMeasure() - 1) * timesig_den; note++) {
					duration += notes[note].getRhythmValue()
;
				}
				
				boolean firstNote = true;
				double firstTime = 0;
				
				for (; note < notes.length && duration < measure
.getMeasure() * timesig_den; note++) {
					if (firstNote) {
						firstTime = duration;
						firstNote = false;
					}
					newPhrase.addNote(notes[note].copy());
					duration += notes[note].getRhythmValue()
;
				}
				

				double offset = firstTime;
				while (offset >= timesig_den) {
					offset -= timesig_den;
				}
				
				double startTime = ((mCurrentMeasure - 1) * time
sig_den) + offset;
				newPhrase.setStartTime(startTime);
				//newPhrase.setStartTime(firstTime);
				
				newPart.add(newPhrase);
				
			}
			
			/* assign a channel to each part
			 * keep drums on MIDI channel 10 (9 in JMusic)
			 * use assigned channel for everything else
			 */
			if(oldPart.getChannel() == 9) {
				newPart.setChannel(9);
			} else {
				newPart.setChannel(measure.getChannel());
			}
			
			// set MIDI program (e.g. 1 is Acoustic Piano)
			newPart.setInstrument(measure.getInstrument());
			
			// perform potential pitch transposition
			Mod.transpose(newPart, measure.getPitch());
			
			// set tempo for the newly added part
			newPart.setTempo(mTempo);
			
			mScore.add(newPart);
			
		}
		
		mCurrentMeasure++;
		
	}
	
	/**
	 * Plays the song that has been built up through JMusic
	 */
	public void play() {
		Play.midi(mScore);
	}
		
	
	/**
	 * Return the length of an input file in measures
	 * @param fileName	The name of the file to count measures in
	 */
	public int length(String fileName) {
		Score s = new Score(fileName);
		Read.midi(s, fileName);
		double last = s.getEndTime() / 4.0;
		int length = (int)Math.round(last);
		
		if (s.getPart(0) == null) {
			throw new Error("Bad MIDI file passed in: " + fileName);
		}
		
		return length;
		
	}
	
	/**
	 * Sets the tempo for generated music
	 * @param tempo  The tempo to generate/play the music at.
	 */
	public void setTempo(int tempo) {
		mTempo = tempo;
	}
	
}




Filename: Runtime//src/upbeat/jmusiclib/JMusicWrapperInterface.java
Author: Fan
package upbeat.jmusiclib;

import java.util.LinkedList;

import upbeat.types.Measure;

public interface JMusicWrapperInterface {

	/**
	 * Used by the Manager class to pass a new measure of music to JMusic. A
t
	 * the moment, this should just be appended onto the end of a MIDI file.
	 * Eventually, we'll want to add in another method for actually playing 
this
	 * stuff in real time.
	 * 
	 * @param newMeasure
	 *            This is a linked list containing a bunch of measures. The
	 *            measures of music in newMeasure should be played
	 *            <i>simultaneously</i>. Thus, even though there may be many
	 *            {@link Measure} objects passed to AppendNextMeasure, they 
only
	 *            actually produce one measure of music in the final song.
	 */
	public void AppendNextMeasure(LinkedList<Measure> newMeasure);

	/**
	 * Plays the song that has been built up through JMusic
	 */
	public void play();

	/**
	 * Return the length of an input file in measures
	 * 
	 * @param fileName
	 *            The name of the file to count measures in
	 */
	public int length(String fileName);

	/**
	 * Sets the tempo for generated music
	 * 
	 * @param tempo
	 *            The tempo to generate/play the music at.
	 */
	public void setTempo(int tempo);
}




Filename: Runtime//src/upbeat/jmusiclib/JMusicWrapperPrinter.java
Author: Fan
package upbeat.jmusiclib;

import java.util.LinkedList;

import upbeat.types.Measure;

public class JMusicWrapperPrinter implements JMusicWrapperInterface {

	private LinkedList<LinkedList<Measure>> score = new LinkedList<LinkedLis
t<Measure>>();
	private int currentMeasure = 1;
	@Override
	public void AppendNextMeasure(LinkedList<Measure> newMeasure) {

		System.out.println("----Measure: " + currentMeasure + " --------
");
		for (Measure m : newMeasure) {
			System.out.println(m);
		}
		System.out.println("----------------------------------");
		
		score.add(newMeasure);
		currentMeasure++;
	}

	/**
	 * Fetch the length from the file name
	 * the file name should looks like "melody.mid.4"
	 */
	@Override
	public int length(String fileName) {
		try 
		{
			return Integer.parseInt(fileName.split(".")[2]);
		} catch (Exception e) {
			return 1;
		}
	}

	@Override
	public void play() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setTempo(int tempo) {
		// TODO Auto-generated method stub
		
	}

}




Filename: Runtime//src/upbeat/jmusiclib/MeasureList.java
Author: Fan
package upbeat.jmusiclib;

import java.util.LinkedList;

import upbeat.types.Measure;

public class MeasureList {
	public LinkedList<Measure> measures;
}




Filename: Runtime//src/upbeat/Manager.java
Author: Matt
package upbeat;

import upbeat.types.Cue;
import java.util.LinkedList;
import upbeat.jmusiclib.JMusicWrapper;
import upbeat.jmusiclib.JMusicWrapperInterface;

/**
 * This is the interface to the Manager classes.  At the start of the program, t
he
 * {@link UpbeatApplication} is going to create an object that implements the 
 * Manager interface.<br/>
 * 
 * The Manager will be the central "hub" of the runtime environment and, as such
,
 * must interact with all of the different components in the runtime environment
.
 * Described below are the classes that a Manager interacts with and what the
 * purpose of said interaction is.  Note: The Manager interface only provides
 * methods for other classes to interact with the Manager with.  All methods
 * that allow a Manager to affect outgoing changes are left up to the implementa
tion.<br/>
 * 
 * <ul>
 * <li><b>{@link UpbeatApplication}:</b> The Manager is created by the UpbeatApp
lication.
 * Furthermore, the UpbeatApplication is going to give the Manager pointers to
 * the {@link Conductor} and {@link Musician}s that the Manager needs to interac
t
 * with.  Finally, the UpbeatApplication gives the Manager the name of the input
 * (either a file or some source of real-time data, depending on the implementat
ion
 * of the Manager).  From a high level point of view, the Manager is responsible
 for
 * reading the input and providing it to the {@link Conductor} in a timely manne
r.
 * However, it is likely that this particular functionality will be factored int
o
 * its own class.  Since the type of input is implementation-specific, it is not
 * dealt with here.</li>
 * 
 * <li><b>{@link Conductor}:</b> As stated above, the Manager is responsible for
 providing
 * timely input to the Conductor.  However, the Manager is also responsible for
 * handling {@link Cue}s given to it by the Conductor.  Therefore, this interfac
e
 * provides methods for the Conductor to add Cues.  The Manager is then responsi
ble
 * for making sure that these Cues are dispatched to the {@Musician}s in a timel
y
 * fashion.</li>
 * 
 * <li><b>{@link Musician}:</b> The Manager is responsible for providing {@link 
Cue}s to
 * the Musicians in a timely fashion.  Tentatively, in the offline case the
 * Manager will also have to stitch together the individual tracks created
 * by the Musicians.  However, all of this functionality is going to be in
 * the Musician interface, so there will be very little in the Manager interface
 * having to do with Musicians.</li>
 * </ul>
 * 
 * @author Matt
 *
 */
public abstract class Manager {
	protected TempoOptions mOptions;
	protected ConductorInterface mConductor;
	protected LinkedList<MusicianInterface> mMusicians;
	protected JMusicWrapperInterface jMusicWrapper;
	
	
	protected Manager(){
		mMusicians = new LinkedList<MusicianInterface>();
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the input
 source
	 * @param source	the source of the input.  Could be a file name, 
RSS feed, etc....
	 * @return	returns whether or not the input source was successfully
 accessed.
	 */
	public abstract boolean SetInputSource( String source );
	
	public void SetJMusicWrapper(JMusicWrapperInterface jMusicWrapper) {
		this.jMusicWrapper = jMusicWrapper;
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the {@lin
k TempoOptions}
	 * of the output music.
	 * @param options	the tempo options to be used when generating mus
ic.
	 */
	public void SetTempoOptions( TempoOptions options ) {
		mOptions = options;
		// Let the MIDI code know the tempo of the song
		jMusicWrapper.setTempo(options.TEMPO);
	}
	
	/**
	 * This method gets the tempo options.
	 * @return	the tempo options
	 */
	public TempoOptions GetTempoOptions() {
		return mOptions;
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the {@lin
k Conductor}.
	 * Note that there may only be one Conductor per Manager.
	 * @param conductor		A reference to the {@link Conductor}.  M
ust be already instantiated!
	 */
	public void SetConductor( ConductorInterface conductor ) {
		mConductor = conductor;
	}
	
	/**
	 * Adds a reference to a {@link Musician} to the Manager's stable of Mus
icians.  This is
	 * used by the {@link UpbeatApplication} after it has instantiated each 
of the Musicians<br/><br/>
	 * 
	 * Note that when we add a Musician, we will need to give it an appropri
ate {@link Track} class.  Which
	 * MusicMaker we give it will be dependent on whether we're running in r
eal time or offline.  Therefore, we
	 * will leave the implementation of this method to the Offline and RealT
ime subclasses of Manager.
	 * 
	 * @param musician	A reference to the {@link Musician}.  Must be al
ready instantiated!
	 */
	public abstract void AddMusician( MusicianInterface musician );
	
	/**
	 * Once the {@link Conductor}, {@link Musician}s, and input have been se
t, call this to
	 * start making music!
	 * @throws Exception 
	 */
	public abstract void MakeSomeMusic() throws Exception;
	
	/**
	 * Used by the {@link Conductor} to add cues to the score.
	 * @param cueToAdd	Reference to the cue to add.  Note that in the i
mplementations, you
	 * should always make a copy of this!!!!!!
	 */
	public abstract void AddCueToScore( Cue cueToAdd );
}








Filename: Runtime//src/upbeat/Musician.java
Author: Fan Lin
package upbeat;

import upbeat.types.Cue;
import upbeat.types.Measure;

/**
 * The base class of compiler generated Musicians, providing all necessary
 * methods of music manipulation.
 * 
 * @author Fan Lin
 * 
 */
public abstract class Musician implements MusicianInterface {
	private Track mTrack;
	private int channel = 0;
	
	protected Musician(int chan) {
		mTrack = new Track();
		channel = chan;
		if(channel == 9 || channel > 15) { // special case for drum chan
nel - skip it!
			throw new Error("Upbeat currently only supports 15 music
ians, none of them on channel 10, to comply with MIDI restrictions");
		}
	}
	
	protected Track getMusicMaker()
	{
		return mTrack;
	}
	
	public int getChannel() {
		return channel;
	}

	public Measure GetNextMeasure() {
		return mTrack.getNextMeasure();
	}

	/**
	 * The main function of the Musician.
	 * @param cue
	 */
	public abstract void processCue(Cue cue) throws Exception;	
}




Filename: Runtime//src/upbeat/MusicianInterface.java
Author: Matt
package upbeat;

import upbeat.types.Cue;
import upbeat.types.Measure;

public interface MusicianInterface {
	public int getChannel();
	public Measure GetNextMeasure();
	public abstract void processCue(Cue cue) throws Exception;	
}




Filename: Runtime//src/upbeat/OfflineManager.java
Author: Matt
package upbeat;

import upbeat.types.Cue;
import upbeat.types.CueComparator;
import upbeat.types.Measure;

import upbeat.jmusiclib.JMusicWrapper;
import upbeat.jmusiclib.JMusicWrapperPrinter;

import java.util.PriorityQueue;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;

import java.io.*;
import java.util.Scanner;


public class OfflineManager extends Manager {

	private OfflineInput mInput;
	private PriorityQueue<Cue> mQueue;
	
	public OfflineManager() {
		super();
		
		mInput = new OfflineInput();
		Comparator<Cue> comparator = new CueComparator();
        mQueue = new PriorityQueue<Cue>(10, comparator);
	}
	
	@Override
	public void AddCueToScore(Cue cueToAdd) {
		mQueue.add( cueToAdd );
		
	}

	@Override
	public void MakeSomeMusic() throws Exception {
		if( mConductor == null ) {
			throw new Exception("OfflineManager.MakeSomeMusic(): Mus
t instantiate Conductor before calling me!");
		}
		
		if( mMusicians.size() == 0 ) {
			throw new Exception("OfflineManager.MakeSomeMusic(): Mus
t create some Musicians before calling me!");
		}
		
		if( mOptions == null ) {
			throw new Exception("OfflineManager.MakeSomeMusic(): Mus
t instantiate TempoOptions before calling me!");
		}
		
		if( jMusicWrapper == null ) {
			throw new Exception("OfflineManager.MakeSomeMusic(): Mus
t set a jMusicWrapper before calling me!");
		}
		
		MakeCueList();
		try {
			DistributeCues();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
		MakeFinalSong();
		Play();
	}
	
	/**
	 * This goes through the input one piece at a time.  It then calls {@lin
k Conductor.Conduct} for
	 * the input.  The {@link Conductor} constructs the Cue list by calling 
{@link AddQueueToScore}.
	 * Once the input is finished, our {@link Cue} list will be constructed 
and we can then begin
	 * sending them off to {@link Musician}s.
	 */
	private void MakeCueList() {
		int currentMeasure = 1;
		
		// If the user does not specify an input source, then we want to
 call Conduct exactly once.
		if( !mInput.InputSourceSet() ) {
			mConductor.Conduct(currentMeasure, 0.0, true);
		}
		else {
			while( !mInput.EndOfFile() ){
				double nextInput = mInput.GetNextInput();
				boolean done = mInput.EndOfFile();
				mConductor.Conduct(currentMeasure, nextInput, do
ne);
				currentMeasure++;
			}
		}
	}
	
	/**
	 * This distributes the {@link Cue}s to the {@link Musician}s.  It just 
loops over the
	 * {@link PriorityQueue} of Cues and sends them off to the different Mus
icians.
	 * @throws Exception 
	 */
	private void DistributeCues() throws Exception {
		while( mQueue.size() > 0 ) {
			Cue nextCue = mQueue.poll();
			
			Iterator< MusicianInterface > iterator = mMusicians.iter
ator();
		    while (iterator.hasNext()) {
		    	iterator.next().processCue( nextCue.clone() );
		    }
		}
	}
	
	/**
	 * Once the {@link Conductor} has processed all the input and the {@link
 Musician}s have
	 * made the {@link Measure} data structures that will be used internally
 to represent our
	 * output song, we need to actually output the song.  This method goes t
hrough all the
	 * Musicians and creates the final song, measure by measure.  It then pa
sses each measure
	 * to the {@link JMusicWrapper} object to be turned into a MIDI file.
	 */
	private void MakeFinalSong() {
		
		// We decided as a convention that for offline songs, we will pr
oduce
		// a song that has a number of measures equal to the size of the
 input
		// (in doubles) plus 32.  The extra 32 measures at the end are s
o
		// that we can have things like a finale at the end.
		int totalSongLength = mInput.HowMuchInputRead() + 32;
		
		for( int i = 0; i < totalSongLength; i++ ) {
			LinkedList<Measure> nextMeasure = new LinkedList<Measure
>();
			Iterator< MusicianInterface > iterator = mMusicians.iter
ator();
		    while (iterator.hasNext()) {
		    	
		    	MusicianInterface mus = iterator.next();
		    	Measure meas = mus.GetNextMeasure();
		    	meas.setChannel(mus.getChannel());
		    	nextMeasure.add( meas );
		    	
		    }
		    
		    jMusicWrapper.AppendNextMeasure(nextMeasure);
		}
	}
	
	/**
	 * This takes all the measures collected in the {@link JMusicWrapper} ob
ject and sends them
	 * out as MIDI data.
	 */
	private void Play() {
		jMusicWrapper.play();
	}

	@Override
	public boolean SetInputSource(String source) {
		return mInput.SetInputSource(source);
		
	}
	
	@Override
	public void AddMusician( MusicianInterface musician ) {
		if( musician != null )
			mMusicians.addLast(musician);
	}

}

/**
 * The OfflineInput class is used by the OfflineManager to access data from a fi
le.
 * An OfflineInput object needs to be provided with a path to an input file.  It
 then
 * opens the file and reads in the input (in our case whitespace delimited doubl
es).
 * From there, every time GetNextInput is called, it returns the next chunk of i
nput
 * in the file.
 * 
 * @author Matt
 *
 */
class OfflineInput {
	private boolean mInputSet;
	private Scanner mInputSource;
	private int mInputRead;
	
	OfflineInput() {
		mInputSet = false;
		mInputRead = 0;
	}
	
	/**
	 * How many pieces of input have been read?
	 * @return	the number of doubles that have been read from the input
	 */
	int HowMuchInputRead(){
		return mInputRead;
	}
	
	/**
	 * Sets the input source.  This should be a whitespace delimited text fi
le full of doubles.
	 * @param source	a string telling the source of input.  In the ca
se that the input is a file,
	 * 					then source should be a path to 
a file on the hard drive.
	 * @return			returns true if successfully able to acc
ess input, false otherwise.
	 */
	boolean SetInputSource( String source ){
		try {
			mInputSource = new Scanner(new BufferedReader(new FileRe
ader(source)));
			mInputSet = true;
		} catch (FileNotFoundException e) {
			System.out.printf("Error: Could not find input file %s.\
n", source);
			e.printStackTrace();
			mInputSet = false;
		}

		return mInputSet;
	}
	
	/**
	 * Says whether or not a valid source of input has been set.
	 * @return	whether or not the source of input has been set.
	 */
	boolean InputSourceSet() {
		return mInputSet;
	}
	
	/**
	 * This returns whether or not we've reached the end of the input source
.
	 * @return	whether or not we've reached the end of the input source
.
	 */
	boolean EndOfFile() {
		if( mInputSource == null )
			return true;
		else {
			
			// Scan ahead until we reach the next valid input value.
			while( !(mInputSource.hasNextDouble()) && mInputSource.h
asNext() ) {
				mInputSource.next();
	        }
			
			// If there is a next valid input value, return true, ot
herwise we're at the end!
			return !(mInputSource.hasNextDouble());
		}
	}
	
	/**
	 * This gets the next input.  Always make sure you are NOT at the end of
 the file (using {@link EndOfFile})
	 * before you call this as there is no special EOF double.
	 * @return	the next piece of input.
	 */
	double GetNextInput(){
		double ret = 0.0;
		
		if( mInputSource == null )
			return 0.0;
		
		while( !(mInputSource.hasNextDouble()) && mInputSource.hasNext()
 ) {
			mInputSource.next();
        }
		
		if( mInputSource.hasNext() )
			ret = mInputSource.nextDouble();
		
		mInputRead++;
		
		return ret;
	}
}



Filename: Runtime//src/upbeat/TempoOptions.java
Author: Matt
package upbeat;

/**
 * 
 * Provides an interface and several variables for keeping track of tempo and ti
me signature.  In an Upbeat
 * source file, we will set these as part of the header, but they will belong to
 neither the {@link Conductor} nor
 * the {@link Musician}s, and must be accessible to the entire runtime environme
nt.  Therefore the compiler will
 * need to implement this interface and initialize the fields appropriately.
 *
 * @author Matt
 */
public abstract class TempoOptions {
	
	/**
	 * Tempo of the piece in beats per minute.
	 */
	public int TEMPO;
	
	/**
	 * Top part of the time signature.  This represents how many beats there
 are per measure.
	 */
	public int TIME_SIGNATURE_TOP;
	
	/**
	 * Bottom part of the time signature.  This represents how long a beat i
s.  For example,
	 * a value of 4 means that a quarter note counts as one beat.
	 */
	public int TIME_SIGNATURE_BOTTOM;
}




Filename: Runtime//src/upbeat/Track.java
Author: Fan Lin
package upbeat;

import java.util.LinkedList;

import upbeat.types.Measure;
import upbeat.types.MusicPhrase;

/**
 * Generate music for each Musician.
 * 
 * @author Fan Lin
 * 
 */
public class Track {
	static int maxVol = 100;
	static int minVol = 0;
	static int maxPitch = 36;
	static int minPitch = -36;

	private LinkedList<Measure> measureBuffer; 
	private int passedMeasure;
	private MusicPhrase currentPhrase;
	
	public Track() {
		measureBuffer = new LinkedList<Measure>();
		passedMeasure = 1;
		currentPhrase = MusicPhrase.getREST();
		currentPhrase.setRepeat(-1);
		
	}
	
	public void appendPhraseAt(MusicPhrase p, int measureNum) throws Excepti
on
	{
		playForwardTo(measureNum);
		p.reset();
		currentPhrase = p;
	}

	private void playForwardTo(int measureNum) throws Exception {
		int targetBufferSize = measureNum - passedMeasure;
		if (targetBufferSize < 0) {
			throw new Exception("Cannot change measures already prod
uced.");
		}
		
		while (targetBufferSize < measureBuffer.size()) {
			measureBuffer.removeLast();
		}
		
		while (targetBufferSize > measureBuffer.size()) {
			
			Measure m = currentPhrase.playNext();
			if (m != null) { 
				measureBuffer.addLast(m);
			} else {
				measureBuffer.addLast(Measure.REST);
			}
		}
	}
	
	public Measure getNextMeasure() {
		passedMeasure++;
		Measure m = Measure.REST;
		
		if (measureBuffer.size() > 0) {
			m = measureBuffer.removeFirst();
		} else {
			Measure t = currentPhrase.playNext();
			if (t != null) {
				m = t;
			}
		}
		if (!m.getIsReady()) {
			m.setInstrument(instrumentId);
			m.setVolume(volume);
			m.setPitch(pitch);
			m.setIsReady(true);
		}
		return m;
	}
	
	private int volume = 100;
	private int pitch = 0;
	private int instrumentId = 0;
	
	private void setParameterBefore(int measureNum) {
		try {
			playForwardTo(measureNum);
		} catch (Exception e) {
			return;
		}
		
		for (Measure m : measureBuffer) {
			if (!m.getIsReady()) {
				m.setVolume(volume);
				m.setPitch(pitch);
				m.setInstrument(instrumentId);
				m.setIsReady(true);
			}
		}
	}
	
	public void changeVolumeTo(int volume, int measureNum) {
		if(volume > maxVol) {
			System.err.println("Warning: attempt to set volume to " 
+ volume + " > " + maxVol + ".  Using " + maxVol + ".");
			volume = maxVol;
		}
		if(volume < minVol) {
			System.err.println("Warning: attempt to set volume to " 
+ volume + " < " + minVol + ".  Using " + minVol + ".");
			volume = minVol;
		}
		setParameterBefore(measureNum);
		this.volume = volume;
	}
	
	public void changeVolumeBy(int volume, int measureNum) {
		setParameterBefore(measureNum);
		this.volume += volume;
		if(this.volume > maxVol) {
			System.err.println("Warning: attempt to set volume to " 
+ this.volume + " > " + maxVol + ".  Using " + maxVol + ".");
			this.volume = maxVol;
		}
		if(this.volume < minVol) {
			System.err.println("Warning: attempt to set volume to " 
+ this.volume + " < " + minVol + ".  Using " + minVol + ".");
			this.volume = minVol;
		}
	}
	
	public void changePitchTo(int pitch, int measureNum) {
		if(pitch > maxPitch) {
			System.err.println("Warning: attempt to set pitch to " +
 pitch + " > " + maxPitch + ".  Using " + maxPitch + ".");
			pitch = maxPitch;
		}
		if(pitch < minPitch) {
			System.err.println("Warning: attempt to set pitch to " +
 pitch + " < " + minPitch + ".  Using " + minPitch + ".");
			pitch = minPitch;
		}
		setParameterBefore(measureNum);
		this.pitch = pitch;
		
	}
	public void changePitchBy(int pitch, int measureNum) {
		setParameterBefore(measureNum);
		this.pitch += pitch;
		if(this.pitch > maxPitch) {
			System.err.println("Warning: attempt to set pitch to " +
 this.pitch + " > " + maxPitch + ".  Using " + maxPitch + ".");
			this.volume = maxPitch;
		}
		if(this.pitch < minPitch) {
			System.err.println("Warning: attempt to set pitch to " +
 this.pitch + " < " + minPitch + ".  Using " + minPitch + ".");
			this.volume = minPitch;
		}
	}
	
	public void changeInstrumentTo(int instrumentId, int measureNum) {
		setParameterBefore(measureNum);
		this.instrumentId = instrumentId;
	}
	
	public void changeInstrumentBy(int instrumentId, int measureNum) {
		setParameterBefore(measureNum);
		this.instrumentId += instrumentId;
	}
}




Filename: Runtime//src/upbeat/types/Cue.java
Author: Matt
package upbeat.types;

/**
 *
 * This class holds all data associated with Cues.  {@link Conductor}s will gene
rate Cues
 * that will then be passed to the {@link Manager} class.  The {@link Manager} w
ill then
 * keep track of the Cues based on their time and give them to {@link Musician}s
 when
 * necessary.</br>
 * 
 * Cues have three pieces of data associated with them, a name, a time, and an a
dditional
 * piece of data in the form of an integer.
 * 
 * @author Matt
 */

public class Cue implements Cloneable {
	private String name;
	private int time;
	public int data;
	
	/**
	 * Default constructor.  Sets the name to "" and the data to 0 and time 
to 1.
	 */
	public Cue() {
		this.name = new String("");
		this.data = 0;
		this.time = 1;
	}
	
	/**
	 * Constructor most likely to be used in Upbeat programs.  Initializes d
ata
	 * and time both to 0.
	 * 
	 * @param name	the name of the Cue.
	 */
	public Cue( String name ) {
		setName( name );
		this.data = 0;
		this.time = 0;
	}
	
	/**
	 * Copy constructor.  Used by clone method to create a new Cue with diff
erent values
	 * @param c		the Cue to be copied
	 * 
	 * @see		#clone()
	 */
	public Cue( Cue c ) {
		this.setName(c.getName());
		this.setData(c.getData());
		this.setTime(c.getTime());
	}
	
	/**
	 * Used for creating a new Cue object with all the same values as this.
	 */
	public Cue clone(){
		return new Cue( this );
	}

	/**
	 * Sets the name.
	 * 
	 * @param name	value of the new name we're going to use.
	 */
	public void setName(String name) {
		this.name = new String( name );
	}

	/**
	 * Gets the name.
	 * 
	 * @return	copy of the name of this object.  Modifications to the c
opy will
	 * 			not affect the original.
	 */
	public String getName() {
		return new String(name);
	}
	
	/**
	 * Sets the time.
	 * 
	 * @param time	the new time that this Cue will occur.
	 */
	public void setTime(int time) {
		this.time = time;
	}

	/**
	 * Gets the time.
	 * 
	 * @return	the time this Cue needs to be executed.
	 */
	public int getTime() {
		return time;
	}

	/**
	 * Sets the data.
	 * 
	 * @param data	the data associated with this Cue.
	 */
	public void setData(int data) {
		this.data = data;
	}

	/**
	 * Gets the data.
	 * 
	 * @return	the integer piece of data associated with this Cue.
	 */
	public int getData() {
		return data;
	}
}





Filename: Runtime//src/upbeat/types/CueComparator.java
Author: Matt
package upbeat.types;

import java.util.Comparator;

/**
 * This is used by our ${@link PriorityQueue} to sort the @{link Cue}s properly.
 * @author Matt
 *
 */
public class CueComparator implements Comparator<Cue> {

	/**
	 * Determines whether or not one {@link Cue} comes before another.
	 */
	@Override
	public int compare(Cue arg0, Cue arg1) {
		if( arg0 == null && arg1 == null )
			return 0;
		if( arg0 == null )
			return 1;
		if( arg1 == null )
			return -1;
        if(arg0.getTime() < arg1.getTime())
        {
            return -1;
        }
        if(arg0.getTime() > arg1.getTime())
        {
            return 1;
        }
        
		return 0;
	}

}




Filename: Runtime//src/upbeat/types/Measure.java
Author: Fan
package upbeat.types;

public class Measure {
	public static final Measure REST = new Measure("REST", 0);
	
	String midifileName;
	int measure;
	private int volume = 100;
	private int pitch = 0;
	private int instrument = 0;
	private int channel = 0;
	
	private boolean ready = false;
	
	public Measure(String fileName, int measure) {
		this.midifileName = fileName;
		this.measure = measure + 1;
	}
	
	public String toString() {
		return String.format("%s, M:%d V:%d P:%d I:%d", midifileName, me
asure, volume, pitch, instrument);
	}
	
	public void setChannel(int chan) {
		channel = chan;
	}
	
	public int getChannel() {
		return channel;
	}

	public void setInstrument(int instrument) {
		this.instrument = instrument;
	}
	
	public int getInstrument() {
		return instrument;
	}

	public void setPitch(int pitch) {
		this.pitch = pitch;
	}


	public int getPitch() {
		return pitch;
	}

	public void setVolume(int volume) {
		this.volume = volume;
	}

	public int getVolume() {
		return volume;
	}
	
	public String getMidiName() {
		return midifileName;
	}
	
	public int getMeasure() {
		return measure;
	}

	public void setIsReady(boolean ready) {
		this.ready = ready;
	}
	
	public boolean getIsReady() {
		return ready;
	}
}




Filename: Runtime//src/upbeat/types/MusicPhrase.java
Author: Fan Lin
package upbeat.types;

import java.util.ArrayList;

import upbeat.jmusiclib.JMusicWrapper;


/**
 * This class stands for a piece of playable music. It could related to a single
 * MIDI file, or it could be a combination of different phrases.
 * 
 * @author Fan Lin
 * 
 */



public class MusicPhrase {
	// Static Fields.
	public static MusicPhrase getREST() {
		return new MusicPhrase("REST", 1);
	}

	// Basic Info
	String midiFileName = null;
	int length = 0;
	int repeats = 1;
	ArrayList<MusicPhrase> children = null;
	
	/**
	 * Create an empty Music Phrase.
	 */
	public MusicPhrase()
	{
		children = new ArrayList<MusicPhrase>();
	}
	
	/**
	 * Create a music phrase from a MIDI file.
	 * 
	 * @param midiFileName
	 */
	public MusicPhrase(String midiFileName)
	{
		this(midiFileName, (new JMusicWrapper()).length(midiFileName));
	}
	
	/**
	 * Create a music phrase from a MIDI file.
	 * 
	 * @param midiFileName
	 */
	public MusicPhrase(String midiFileName, int length)
	{
		this.midiFileName = midiFileName;
		this.length = length;
	}
	
	/** 
	 * Set the number of repeat of current phrase.
	 * 
	 * @param n number of repeats, -1 for repeat forever
	 */
	public void setRepeat(int n)
	{
		repeats = n; 
	}
	
	/**
	 * Get the the length of the phrase, includes all children phrases and r
epeates.
	 * 
	 * @return phrase length in number of measures, -1 for infinite.
	 */
	public int getLength() {
		if (repeats >= 0) {
			return this.length * repeats;
		} else {
			return -1;
		}
	}
	
	public void appendPhrase(MusicPhrase p) throws Exception {
		if (isLeaf()) { 
			throw new Exception("Cannot append to a leaf phrase");
		}
		
		children.add(p);
		if (p.getLength() == -1) {
			this.length = -1;
		} else {
			this.length += p.getLength();
		}		
	}
	
	public boolean isLeaf() {
		return (midiFileName != null);
	}
	
	public boolean isInfinte() {
		return (repeats == -1);
	}
	
	// Playing control variables.
	int repeatsLeft;
	int currentChildPlaying; 
	int currentMeasurePlaying;
	
	// Playing control methods.
	public void reset() {
		repeatsLeft = repeats;
		if (!isLeaf()) {
			for (MusicPhrase p : children) {
				p.reset();
			}
			currentChildPlaying = 0;
		} else {
			currentMeasurePlaying = 0;
		}
	}
	
	public Measure playNext() {
		if (repeatsLeft == 0 && !isInfinte()) {
			return null;
		}
		
		if (isLeaf()) {
			while (repeatsLeft > 0 || isInfinte()) {
				if (currentMeasurePlaying < length) {
					return new Measure(midiFileName, current
MeasurePlaying++);
				} else {
					repeatsLeft--;
					currentMeasurePlaying= 0;
				}
			}
			return null;
		} else {
			while (repeatsLeft > 0 || isInfinte()) {
				while (currentChildPlaying < children.size()) {
					Measure ret = children.get(currentChildP
laying).playNext();
					if (ret != null) {
						return ret;
					}
					currentChildPlaying++;
				}
				
				repeatsLeft--;
				for (MusicPhrase p : children) {
					p.reset();
				}
				currentChildPlaying = 0;
			}
			return null;
		}
		
	}
}




Filename: Runtime//src/upbeat/UpbeatApplication.java
Author: Matt
package upbeat;

/**
 * This is the interface to the actual UpbeatApplication class.  Right now, ther
e's nothing in it.
 * This interface is probably superfluous, as the compiler will generate all the
 necessary methods
 * on its own.
 * 
 * @author Matt
 *
 */
public interface UpbeatApplication {
}




Filename: Runtime//test/upbeat/DataHandlerTest.java
Author: Fan Lin

/**
 * 
 * Unit test of DataHandler.java
 * 
 * @author Fan Lin
 */

package upbeat;

import junit.framework.TestCase;

public class DataHandlerTest extends TestCase {

	public void testDataHandler() throws Exception {
		DataHandler dh = new DataHandler();
		
		for (int i = 0; i < 100; i++) {
			dh.FeedData(i / 10.0);
			dh.SetMore(true);
		}
		
		assertEquals(99 / 10.0, dh.CurrentValue(), 0.00001);
		assertEquals(0 / 10.0, dh.ValueAt(0), 0.00001);
		assertEquals(true, dh.GetMore());
		
		dh.SetMore(false);
		assertEquals(false, dh.GetMore());
		
		// Test if the exception is thrown if the index is out of range.
		do {
			try {
				dh.ValueAt(-1);
			} catch (IndexOutOfBoundsException e){
				break;
			}
			throw new Exception("Exception not thrown!");
		} while (false);
		
		do {
			try {
				dh.ValueAt(101);
			} catch (IndexOutOfBoundsException e){
				break;
			}
			throw new Exception("Exception not thrown!");
		} while (false);
	}
}




Filename: Runtime//test/upbeat/OfflineManagerTest.java
Author: Fan
package upbeat;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.EasyMock.verify;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import junit.framework.TestCase;

import org.easymock.IArgumentMatcher;

import upbeat.jmusiclib.JMusicWrapperInterface;
import upbeat.types.Measure;


class MultiCaptureMatcher<T> implements IArgumentMatcher {
	 
    Collection<T> captureDestination;
 
    public MultiCaptureMatcher(Collection<T> captureDestination) {
        this.captureDestination = captureDestination;
    }
 
    @Override
    public void appendTo(StringBuffer buffer) {
        buffer.append("multiCapture(").append(captureDestination.toString()).app
end(")");
    }
 
    @SuppressWarnings("unchecked")
	@Override
    public boolean matches(Object actual) {
        captureDestination.add((T) actual);
        return true;
    }
 
    public static <S> S multiCapture(Collection<S> destination) {
      reportMatcher(new MultiCaptureMatcher<S>(destination));
      return null;
  }
}


public class OfflineManagerTest extends TestCase {

	public void testOfflineManager() throws Exception {
		Manager man = new OfflineManager();
		
		
		ConductorInterface cond = createMock(ConductorInterface.class);
		cond.Conduct(1, 0.0, true);
		replay(cond);
		
		MusicianInterface m1 = createMock(MusicianInterface.class);
		for (int i = 0; i < 32; i++) {
			expect(m1.GetNextMeasure()).andReturn(new Measure("midi1
", i));	
		}
		
		expect(m1.getChannel()).andReturn(0).anyTimes();
		replay(m1);

		MusicianInterface m2 = createMock(MusicianInterface.class);
		for (int i = 0; i < 32; i++) {
			expect(m2.GetNextMeasure()).andReturn(new Measure("midi2
", i));	
		}
		expect(m2.getChannel()).andReturn(1).anyTimes();
		replay(m2);

		JMusicWrapperInterface jMusic = createMock(JMusicWrapperInterfac
e.class);
		List<LinkedList<Measure>> captured = new LinkedList<LinkedList<M
easure>>();
		
		
		jMusic.AppendNextMeasure(MultiCaptureMatcher.multiCapture(captur
ed));
		expectLastCall().anyTimes();
		jMusic.play();
		replay(jMusic);
		
		do {
			try {
				man.MakeSomeMusic();		
			} catch(Exception e) {
				assertTrue(e.getMessage().contains("OfflineManag
er.MakeSomeMusic(): Must instantiate Conductor before calling me!"));
				break;
			}
			throw new Exception("Exception not thrown!");
		} while(false);
		
		man.SetConductor(cond);
		
		do {
			try {
				man.MakeSomeMusic();		
			} catch(Exception e) {
				assertTrue(e.getMessage().contains("OfflineManag
er.MakeSomeMusic(): Must create some Musicians before calling me!"));
				break;
			}
			throw new Exception("Exception not thrown!");
		} while(false);
		
		man.AddMusician(m1);
		man.AddMusician(m2);
		
		do {
			try {
				man.MakeSomeMusic();		
			} catch(Exception e) {
				assertTrue(e.getMessage().contains("OfflineManag
er.MakeSomeMusic(): Must instantiate TempoOptions before calling me!"));
				break;
			}
			throw new Exception("Exception not thrown!");
		} while(false);
		
		man.SetTempoOptions(new TempoOptions() {});
		
		
		do {
			try {
				man.MakeSomeMusic();		
			} catch(Exception e) {
				assertTrue(e.getMessage().contains("OfflineManag
er.MakeSomeMusic(): Must set a jMusicWrapper before calling me!"));
				break;
			}
			throw new Exception("Exception not thrown!");
		} while(false);
		
		man.SetJMusicWrapper(jMusic);
		
		man.MakeSomeMusic();
		int i = 0;
		for (LinkedList<Measure> mlist : captured) {
			assertEquals(2, mlist.size());
			assertEquals("midi1", mlist.get(0).getMidiName());
			assertEquals("midi2", mlist.get(1).getMidiName());
			assertEquals(i+1, mlist.get(0).getMeasure());
			assertEquals(i+1, mlist.get(1).getMeasure());
			i++;
		}
		
		verify(m1);
		verify(m2);
		verify(cond);
		verify(jMusic);
	}
}




Filename: Runtime//test/upbeat/TrackTest.java
Author: Fan
package upbeat;

import junit.framework.TestCase;
import upbeat.types.MusicPhrase;

public class TrackTest extends TestCase {
	public void testSimpleTrack() throws Exception {
		Track t = new Track();
		
		MusicPhrase p1 = new MusicPhrase("midi1", 1);
		p1.setRepeat(3);
		
		MusicPhrase p2 = new MusicPhrase("midi2", 1);
		p2.setRepeat(-1);
		
		MusicPhrase p = new MusicPhrase();
		p.appendPhrase(p1);
		p.appendPhrase(p2);
		
		t.appendPhraseAt(p, 1);
		String[] exp = new String[] {
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0"};

		for (int i = 0; i < 10; i++) {
			assertEquals(exp[i],  t.getNextMeasure().toString());
		}
	}
	
	public void testTrack() throws Exception {
		Track t = new Track();
		
		MusicPhrase p1 = new MusicPhrase("midi1", 1);
		p1.setRepeat(3);
		
		MusicPhrase p2 = new MusicPhrase("midi2", 1);
		p2.setRepeat(-1);
		
		MusicPhrase p = new MusicPhrase();
		p.appendPhrase(p1);
		p.appendPhrase(p2);
		
		t.appendPhraseAt(p, 1);
		String[] exp = new String[] {
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0",
				"midi2, M:1 V:100 P:0 I:0"};

		for (int i = 0; i < 10; i++) {
			assertEquals(exp[i],  t.getNextMeasure().toString());
		}
	}
	
	public void testTrackParameters() throws Exception {
		Track t = new Track();
		MusicPhrase p = new MusicPhrase("midi1", 3);
		p.setRepeat(5);
		t.appendPhraseAt(p, 1);
		
		t.changeVolumeTo(80, 5);
		t.changeVolumeTo(70, 10);
		String[] exp = new String[] {
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:2 V:100 P:0 I:0",
				"midi1, M:3 V:100 P:0 I:0",
				"midi1, M:1 V:100 P:0 I:0",
				"midi1, M:2 V:80 P:0 I:0",
				"midi1, M:3 V:80 P:0 I:0",
				"midi1, M:1 V:80 P:0 I:0",
				"midi1, M:2 V:80 P:0 I:0",
				"midi1, M:3 V:80 P:0 I:0",
				"midi1, M:1 V:70 P:0 I:0",
				"midi1, M:2 V:70 P:0 I:0",
				"midi1, M:3 V:70 P:0 I:0",
				"midi1, M:1 V:70 P:0 I:0",
				"midi1, M:2 V:70 P:0 I:0",
				"midi1, M:3 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0"		
		};
		for (int i = 0; i < 19; i++) {
			assertEquals(exp[i], t.getNextMeasure().toString());
		}
	}
	public void testTrackParameters2() throws Exception {
		Track t = new Track();
		MusicPhrase p = new MusicPhrase("midi1", 3);
		p.setRepeat(5);
		
		t.changeVolumeBy(10, 1);
		t.appendPhraseAt(p, 1);
		
		t.changeVolumeTo(80, 5);
		t.changeVolumeTo(70, 10);
		String[] exp = new String[] {
				"midi1, M:1 V:110 P:0 I:0",
				"midi1, M:2 V:110 P:0 I:0",
				"midi1, M:3 V:110 P:0 I:0",
				"midi1, M:1 V:110 P:0 I:0",
				"midi1, M:2 V:80 P:0 I:0",
				"midi1, M:3 V:80 P:0 I:0",
				"midi1, M:1 V:80 P:0 I:0",
				"midi1, M:2 V:80 P:0 I:0",
				"midi1, M:3 V:80 P:0 I:0",
				"midi1, M:1 V:70 P:0 I:0",
				"midi1, M:2 V:70 P:0 I:0",
				"midi1, M:3 V:70 P:0 I:0",
				"midi1, M:1 V:70 P:0 I:0",
				"midi1, M:2 V:70 P:0 I:0",
				"midi1, M:3 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0",
				"REST, M:1 V:70 P:0 I:0"		
		};
		for (int i = 0; i < 19; i++) {
			assertEquals(exp[i], t.getNextMeasure().toString());
		}
	}
}




Filename: Runtime//test/upbeat/types/MusicPhraseTest.java
Author: Fan
package upbeat.types;

import junit.framework.TestCase;

public class MusicPhraseTest extends TestCase {
	
	public void testOneMusicPhrase() {
		MusicPhrase p = new MusicPhrase("midi1", 4);
		p.setRepeat(3);
		
		Measure next = null;
		p.reset();
		
		String[] exp = new String[] {
				"midi1, M:1 V:1.0 P:0 I:0",
				"midi1, M:2 V:1.0 P:0 I:0",
				"midi1, M:3 V:1.0 P:0 I:0",
				"midi1, M:4 V:1.0 P:0 I:0",
				"midi1, M:1 V:1.0 P:0 I:0",
				"midi1, M:2 V:1.0 P:0 I:0",
				"midi1, M:3 V:1.0 P:0 I:0",
				"midi1, M:4 V:1.0 P:0 I:0",
				"midi1, M:1 V:1.0 P:0 I:0",
				"midi1, M:2 V:1.0 P:0 I:0",
				"midi1, M:3 V:1.0 P:0 I:0",
				"midi1, M:4 V:1.0 P:0 I:0"};
		int i = 0;
		while ((next = p.playNext()) != null) {
			assertEquals(exp[i], next.toString());
			i++;
		}
	}
	
	public void testCombineMusicPhrase() throws Exception {
		MusicPhrase p = new MusicPhrase();
		MusicPhrase p1 = new MusicPhrase("midi1", 4);
		MusicPhrase p2 = new MusicPhrase("midi2", 1);

		p1.setRepeat(1);
		p2.setRepeat(2);
			
		p.appendPhrase(p1);
		p.appendPhrase(p2);
		p.setRepeat(2);
		Measure next = null;
		p.reset();
		String[] exp = new String[]{
			"midi1, M:1 V:1.0 P:0 I:0",
			"midi1, M:2 V:1.0 P:0 I:0",
			"midi1, M:3 V:1.0 P:0 I:0",
			"midi1, M:4 V:1.0 P:0 I:0",
			"midi2, M:1 V:1.0 P:0 I:0",
			"midi2, M:1 V:1.0 P:0 I:0",
			"midi1, M:1 V:1.0 P:0 I:0",
			"midi1, M:2 V:1.0 P:0 I:0",
			"midi1, M:3 V:1.0 P:0 I:0",
			"midi1, M:4 V:1.0 P:0 I:0",
			"midi2, M:1 V:1.0 P:0 I:0",
			"midi2, M:1 V:1.0 P:0 I:0"};

		int i = 0;
		while ((next = p.playNext()) != null) {
			assertEquals(exp[i], next.toString());
			i++;
		}
	}
	
	public void testComplicatedMusicPhrase() throws Exception {
		MusicPhrase p = new MusicPhrase();
		MusicPhrase p1 = MusicPhrase.getREST();
		MusicPhrase p2 = new MusicPhrase("midi2", 2);
		MusicPhrase p3 = new MusicPhrase("midi3", 4);
		MusicPhrase p4 = new MusicPhrase();

		p1.setRepeat(2);
		p2.setRepeat(2);
			
		p.appendPhrase(p1);
		p.appendPhrase(p2);
		p.setRepeat(2);
		
		p4.appendPhrase(p);
		p4.appendPhrase(p3);
		Measure next = null;
		p4.setRepeat(2);
		p4.reset();
		
		String[] exp = new String[] {
				"REST, M:1 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi3, M:1 V:1.0 P:0 I:0",
				"midi3, M:2 V:1.0 P:0 I:0",
				"midi3, M:3 V:1.0 P:0 I:0",
				"midi3, M:4 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"REST, M:1 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi2, M:1 V:1.0 P:0 I:0",
				"midi2, M:2 V:1.0 P:0 I:0",
				"midi3, M:1 V:1.0 P:0 I:0",
				"midi3, M:2 V:1.0 P:0 I:0",
				"midi3, M:3 V:1.0 P:0 I:0",
				"midi3, M:4 V:1.0 P:0 I:0"};
		int i = 0;
		while ((next = p4.playNext()) != null) {
			assertEquals(exp[i], next.toString());
			i++;
		}
	}
}




Filename: Frontend//data/input1
Author: Team
TIME_SIGNATURE 4/4;
TEMPO 160;





Filename: Frontend//data/input2_ss
Author: Team
TIME_SIGNATURE 4/4;
TEMPO 100;

Conductor {
    Conduct(time currentMeasure) {
        cue turnOn;
        turnOn = "TurnOn";
        Add turnOn @m1;
    }
}

Musician "HelloWorld" {
    phrase melody;
    melody = "melody.mid";

    // default Volume is 50
    // default Instrument is 1 which is usually grand piano
    // default Change Pitch is "by 0"

    "TurnOn" {
        ||:melody:||;
    }
}




Filename: Frontend//data/input3
Author: Team

TIME_SIGNATURE 4/4;
TEMPO 120;


Conductor {
    Conduct(time currentMeasure) {
        cue turnOn = "TurnOn";
        Add turnOn @m1;
    }
}

Musician "HelloWorld" {
    phrase melody = "melody.mid";

    // default Volume is 50
    // default Instrument is 1 which is usually grand piano
    // default Change Pitch is "by 0"

    "TurnOn" {
        ||:melody:||;
    }
}




Filename: Frontend//data/input4
Author: Team
TIME_SIGNATURE 4/4;
TEMPO 160;

Conductor {
    cue happy = "HappyCue";
    cue restnow = "RestCue";
    float sum = 0;
    int numvals = 0;

    int CalcAverage() {
        Return (sum / numvals);
    }

    Conduct(time currentMeasure) {
    	int newvol = 50;
        sum = sum + input.currentValue;
        numvals = numvals + 1;

        Case {
            (! input.more) {
                float average = CalcAverage();
                time x = @m1;
                Repeat (x < currentMeasure) {
                    Case {
                        (x == 42) {
                            happy.data = newvol;
                            Add happy x;
                        }
                        (input.valueAt(x) > average) {
                            newvol = newvol + 10;
                            happy.data = newvol;
                            Add happy x;
                        }
                        (TRUE) {
                            newvol = newvol - 10;
                            Add restnow x;
                        }
                    }
                    x = x + @m1;
                }
            }
        }
    }
}

Musician "AwesomeDrummer" {
    phrase beat = "simplebeat.mid";
    phrase crazybeat = "drumsolo.mid";

    int drums = 32;
    Change Volume to 50;
    Change Instrument to drums;
    Change Pitch by 2;

    "HappyCue" {
        Change Volume to $.data;
        Case {
            ($.data > 100) || crazybeat ||: beat | crazybeat :||;
            ($.data in (3, 8]) ||: beat :||;
            (TRUE) || beat ||: REST :||2: beat :||;
        }
    }
    "RestCue" {
        ||: REST :||;
    }
}




Filename: Frontend//data/input5_RT
Author: Team
//Real-Time Example

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor {
    float oldstockprice = 0.0;

    Conduct(time currentMeasure) {
        int pitchshift = 0;
        float newstockprice = input.currentValue;
        cue pitchcue = "ChangePitch";
        cue play = "Play";

        Case {
            ( newstockprice > oldstockprice ) pitchshift = 1;
            ( TRUE ) pitchshift = -1;
        }
        pitchcue.data = pitchshift;
        Add pitchcue currentMeasure;
        Add play currentMeasure;
        oldstockprice = newstockprice;
    }
}

Musician "StockMusician" {
    phrase tune = "data/piano-e1m.mid";

    "ChangePitch" {
        Change Pitch by $.data;
    }
    "Play" {
        ||: tune :||;
    }
}




Filename: Frontend//data/input6_Pres
Author: Team
// Upbeat code example. Plays background music,
// input data going up => triggers "GoingUp" cue
//          going down => triggers "GoingDown" cue

TIME_SIGNATURE 4/4;
TEMPO 140;

Conductor {
    cue up = "GoingUp";
    cue down = "GoingDown";
    cue background = "GoingNowhere";
    float param = 0.95;
    float threshold = 5.0;
    float Avg = 70.0;	// weighted average

    Conduct(time currentMeasure) {
        Avg = param*Avg + (1-param)*input.currentValue;
        Case { 
	    (currentMeasure==1) 
				Add background currentMeasure;
            (input.currentValue > Avg + threshold)
				Add up currentMeasure;
	    (input.currentValue < Avg - threshold)
				Add down currentMeasure;
	} 
    }
}

Musician "Keyboard" {
	phrase intro = "intro.mid";
	phrase bridge = "bridge.mid";
	phrase UpbeatRules = "upbeatrules.mid";	
	phrase SongSnippet = "goingdown.mid";
	
        "GoingNowhere" {
   		||: intro | bridge :||;
	}

	"GoingUp" {
		Change Volume to 100;	// volume is always in [0,100]
		||: UpbeatRules :||2;
	}
	
	"GoingDown" {
		Change Volume to 70;
		||: SongSnippet :||2 ;
	}	
}

Musician "FunkyDrummer" {
	phrase introdrums = "introdrum.mid";
	phrase bridgedrums = "bridgedrum.mid";	
	phrase funkydrums = "drumpatch.mid";
 	phrase cymbal = "cymbal.mid";

 	Change Instrument to 32;	// drums happen to be on MIDI channel 32
    
 	"GoingNowhere" {
		||: introdrums | bridgedrums :||;
    	}

 	"GoingUp" {
        	|| funkydrums | cymbal ||;
    	}
        
}




Filename: Frontend//data/input7_newPres
Author: Team
// Upbeat code example. Plays background music,
// input data going up => triggers "GoingUp" cue
//          going down => triggers "GoingDown" cue

TIME_SIGNATURE 4/4;
TEMPO 140;

Conductor {
	cue intro = "IntroDrums";
    cue up = "GoingUp";
    cue down = "GoingDown";
    cue background = "GoingNowhere";
    float param = 0.95;
    float threshold = 11.0;
    float Avg = 70.0;	// weighted average
    
    Conduct(time currentMeasure) {
        Avg = param*Avg + (1-param)*input.currentValue;
        Case {
	    (currentMeasure==3) 
				Add intro currentMeasure;
        (currentMeasure<=4) { }
        		// no cues; just let the horns play
        (input.currentValue > Avg + threshold)
				Add up currentMeasure;
	    (input.currentValue < Avg - threshold)
				Add down currentMeasure;
		(TRUE)
				Add background currentMeasure;
		}
    }
}

Musician "Melody" {
	phrase melody = "data/fc_melody_main.mid";

	"GoingUp" {
		Change Volume to 100;	// volume is always in [0,100]
		|| melody ||;
	}	
}

Musician "Horns" {
	phrase horns = "data/fc_organ.mid";
	
	||: horns :||;
}

Musician "FunkyDrummer" {
	phrase introdrums = "data/fc_drum_intro.mid";
	phrase drumbeat = "data/fc_drum_loop.mid";	
	
 	Change Instrument to 32;	// drums happen to be on MIDI channel 32
    
 	"IntroDrums" {
		|| introdrums ||;
    }
    
    "GoingNowhere" {
        ||: drumbeat :||;
    }

 	"GoingDown" {
        	||: REST :||;
    }   
}




Filename: Frontend//lexer_parser_src/upbeat-a.yacc
Author: Peyton, Adrian, Matt, Fan
%{
 /* import java.long.Math;
  import java.util.StringTokenizer; */
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;	// Used by the symbol table
import java.util.LinkedList; // Used to create phrases
import java.util.Iterator; // Used to iterate over lists

import upbeat.frontend.upbeatVal;
  
  class upbeatVal {
	  public String code;
	  
	  public int numMusicians;
	  
	  public enum Type { ubVOID, ubINT, ubFLOAT, ubBOOL, ubCUE, ubPHRASE, ub
TIME, ubSTRING };
	  public Type type;
	  
	  public enum UnaryOp { uopPLUS, uopMINUS, uopNOT };
	  public UnaryOp unaryOp;
	  
	  public enum ToBy { To, By };
	  public ToBy toOrBy;
	  
	  public enum ChangeParam { Volume, Pitch, Instrument };
	  public ChangeParam changeParam;
	  
	  public LinkedList<String> listval;
	  
	  // This is used to list the types in the parameter list of functions
	  public LinkedList< upbeatVal.Type > listTypes;
	  public LinkedList< String > listExprs;
	  
	  // We were running into problems because we check to see if functions 
are defined at a different
	  // place as regular identifiers.  As a result, I had to move the check
 to see whether an identifier
	  // exists up a bit higher in the grammar.  As a result, we now have th
is value that tells whether
	  // or not we need to do a definition check.
	  public boolean definitionCheck;
	  
	  public int ival;
	  public double dval;
	  public boolean bval;
	  public String sval;
	  public Object obj;
	  
	  // These are used in range expressions.  rangeLeft and rangeRight
	  // are the strings corresponding with the expressions, and
	  // leftOpen and rightOpen tell whether the interval is open on the
	  // left and right
	  public String rangeLeft;
	  public boolean leftOpen;
	  public Type rangeLeftType;
	  public String rangeRight;
	  public boolean rightOpen;
	  public Type rangeRightType;
	  
	  // This is used in the postfix_expression productions
	  // so we can signal errors when the Upbeat programmer
	  // writes something like:
	  // Foo()()();
	  public boolean alreadyPostFixed;
	  
	  public boolean assignable;

	  public upbeatVal() { }
	  
	  public upbeatVal( ToBy t ) { toOrBy = t; }
	  
	  public upbeatVal( ChangeParam p ) { changeParam = p; }

	  public upbeatVal(int val) { ival=val; }

	  public upbeatVal(double val) { dval=val; }
	  
	  public upbeatVal(boolean val) { bval=val; }

	  public upbeatVal(String val) { code=val; }

	  public upbeatVal(Object val) { obj=val; }
	  
	  public upbeatVal(Type val) { type =val; }
	  
	  public upbeatVal(upbeatVal val) {
		  code = val.code;
		  numMusicians = val.numMusicians;
		  type = val.type;
		  toOrBy = val.toOrBy;
		  changeParam = val.changeParam;
		  ival = val.ival;
		  dval = val.dval;
		  sval = val.sval;
		  obj = val.obj;
	  }
	  
	  public upbeatVal clone() {
		  return new upbeatVal(this);
	  }
  }
  
  class FunctionType {
	  private LinkedList< upbeatVal.Type > mArgTypes;
	  private upbeatVal.Type mReturnType;
	  
	  public FunctionType() {
		  mArgTypes = new LinkedList< upbeatVal.Type >();
		  mReturnType = null;
	  }
	  
	  public void SetReturnType( upbeatVal.Type t ) {
		  mReturnType = t;
	  }
	  
	  public void SetArgs( LinkedList< upbeatVal.Type > args ) {
		  mArgTypes = args;
	  }
	  
	  public void AddArg( upbeatVal.Type arg ) {
		  mArgTypes.add( arg );
	  }
	  
	  public upbeatVal.Type GetReturnType() {
		  return mReturnType;
	  }
	  
	  public LinkedList< upbeatVal.Type > GetArgs() {
		  return mArgTypes;
	  }
	  
	  public boolean CheckArgTypes( LinkedList< upbeatVal.Type > args ){
		  Iterator< upbeatVal.Type > argIter = args.iterator();
		  Iterator< upbeatVal.Type > mArgIter = mArgTypes.iterator();
		  
		  // If either of the types don't match up, return false
		  while( argIter.hasNext() && mArgIter.hasNext() ) {
		      if( argIter.next() != mArgIter.next() )
		    	  return false;
		  }
		      
		  // If the number of arguments doesn't match up, return false
		  if( argIter.hasNext() || mArgIter.hasNext() )
			  return false;
		  
		  return true;
	  }
  }
  
  // Pretty simple symbol table.  Can be expanded if need be
  class SymbolTable {
	  private Hashtable< String, upbeatVal.Type > mSymbols;
	  private Hashtable< String, Integer > mDefLine;
	  
	  private Hashtable< String, FunctionType > mFuncSymbols;
	  private Hashtable< String, Integer > mFuncDefLine;
	  
	  public SymbolTable parent;
	  
	  public boolean inConductor;
	  public boolean inConductorFunc;
	  public boolean inMusician;
	  public boolean inCueResponse;
	  public boolean inRepeat;
	  
	  // This is the name of the function we are in, if it exists...
	  public String myName;
	  public boolean returns;
	  
	  SymbolTable() {
		  // special top-level symbol table
		  parent = null;
		  inConductor = false;
		  inConductorFunc = false;
		  inMusician = false;
		  inCueResponse = false;
		  inRepeat = false;
		  myName = null;
		  mSymbols = new Hashtable<String, upbeatVal.Type>();
		  mDefLine = new Hashtable<String, Integer>();
		  mFuncSymbols = new Hashtable< String, FunctionType >();
		  mFuncDefLine = new Hashtable< String, Integer >();
	  }
	  SymbolTable(SymbolTable p) {
		  parent = p;
		  inConductorFunc = p.inConductorFunc;
		  inConductor = p.inConductor;
		  inMusician = p.inMusician;
		  inCueResponse = p.inCueResponse;
		  inRepeat = p.inRepeat;
		  myName = p.myName;
		  mSymbols = new Hashtable<String, upbeatVal.Type>();
		  mDefLine = new Hashtable<String, Integer>();
		  mFuncSymbols = new Hashtable< String, FunctionType >();
		  mFuncDefLine = new Hashtable< String, Integer >();
	  }
	  
	  public void Returns() {
		  SymbolTable i = this;
		  
		  while( i.inConductorFunc && i.myName != null && i != null) {
			  i.returns = true;
			  i = i.parent;
		  }
		  
		  if( i.inConductorFunc || i.myName != null || i == null ) {
			  throw new Error( "Cannot figure out which function we 
are returning from" );
		  }
	  }
	  
	  public upbeatVal.Type GetCurrentReturnType() {
		  return GetFuncReturnType( myName );
	  }
	  
	  public void AddSymbol( String name, upbeatVal.Type type, int line ) {
		  mSymbols.put( name, type );
		  mDefLine.put( name, line );
	  }
	  
	  public void AddFuncSymbol( String name, FunctionType type, int line ) 
{
		  mFuncSymbols.put( name, type );
		  mFuncDefLine.put( name, line );
	  }
	  
	  public int numSymbols() {
		  if(parent != null) {
			  return mSymbols.size() + parent.numSymbols();
		  }
		  return mSymbols.size();
	  }
	  
	  public int numFuncSymbols() {
		  if(parent != null) {
			  return mFuncSymbols.size() + parent.numFuncSymbols();
		  }
		  return mFuncSymbols.size();
	  }
	  
	  // returns null if the name does not exist!
	  public upbeatVal.Type GetType( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return null;
		  }
		  return i.mSymbols.get( name );
	  }
	  
	  // returns null if the name does not exist!
	  public upbeatVal.Type GetFuncReturnType( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return null;
		  }
		  return i.mFuncSymbols.get( name ).GetReturnType();
	  }
	  
	  public boolean CheckFuncArgTypes( String name,  LinkedList< upbeatVal.
Type > argTypes ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return false;
		  }
		  return i.mFuncSymbols.get( name ).CheckArgTypes( argTypes );
	  }
	  
	  public LinkedList< upbeatVal.Type > GetParamTypes( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return null;
		  }
		  return i.mFuncSymbols.get( name ).GetArgs();
	  }
	  
	  public int GetDefLine( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mDefLine.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return -1;
		  }
		  return i.mDefLine.get( name ); 
	  }
	  
	  public int GetFuncDefLine( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncDefLine.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  // no symbol by that name.
			  return -1;
		  }
		  return i.mFuncDefLine.get( name ); 
	  }
	  
	  public String toString() {
		  String blah = new String();
		  Enumeration<String> keys = mSymbols.keys();
		  while(keys != null && keys.hasMoreElements()) {
			  String k = keys.nextElement();
			  blah = blah + "Var: " + k + " Type: " + mSymbols.get(k
) + "\n";
		  }
		  return blah;
	  }
  }
%}   

/* Declarations */
%token IDENTIFIER CONSTANT STRING_LITERAL
// Special identifier: $
// CONSTANT: 1234(int) 1.234(float) @m1234(Time) REST(Phrase) TRUE(bool)
// STRING_LITERAL "1234"
%right  EQ_ASS
//       =
%left AND_OP OR_OP
//	  and    or
%left EQ_OP NE_OP
//    ==    !=
%left LE_OP GE_OP LESS_OP GREAT_OP
//     <=    >=    <        >
%left '+' '-' 
%left '%'
%left '*' '/'

// Basic Types
%token INT FLOAT BOOL CUE PHRASE TIME INPUT
//     int float bool cue phrase time input

// Special types
%token INPUT CURR_CUE

//Attributes
%token CURRENT_VALUE DATA MORE VALUE_AT 
//     currentValue  data more valueAt

%token CASE RETURN REPEAT BREAK CONTINUE
//     Case Return Repeat Break Continue

%token TIME_SIGNATURE TEMPO
//     TIME_SIGNATURE TEMPO
 
%token ADD CONDUCTOR MUSICIAN
//     Add Conductor Musician

%token IN
//     in

%token CHANGE VOLUME INSTRUMENT PITCH TO BY
//     Change Volume Instrument Pitch to by

%token DB RRPT //REST LRPT
//     || :||  rest    ||:  we have to keep || and : separate   

%start upbeat_src   

//Here's the grammar
%%

upbeat_src
    : header conductor_block musician_blocks
    	{
			$$ = new upbeatVal("Generating compiled Upbeat code for 
" + $3.ival + " musicians.\n");
			
			String app_code = new String();
			
			app_code = app_code.concat("package upbeat.sample;\n\n" 
+
					"import upbeat.jmusiclib.*;\n" +
					"import upbeat.*;\n\n" +
					"public class CompiledUpbeatApplication 
implements UpbeatApplication {\n" +
					"	public static void main( String 
[] args ) {\n" +
"		// Right now, we're just going to assume that there is one input
 argument, and that it is a file name.\n" +
"		// When we implement real time, we will need to check to see if 
there is an additional flag to see\n" +
"		// whether we want real time or not.  The implementation of the 
Manager class we instantiate here will\n" +
"		// be dependent on whether or not we want to run in real time.  
However, for now, just assume it's always\n" +
"		// offline.\n" +
"\n" +		
"		// Create the Manager, Conductor, and Musician(s).\n" +
"		Manager manager;\n" +
"		//if( realtime )\n" +
"		// manager = new RealTimeManager();\n" +
"		//else\n" +
"		manager = new OfflineManager();\n" +
"\n" +		
"		TempoOptions tempoOptions = new CompiledTempoOptions();\n" +
"		Conductor conductor = new CompiledConductor(manager);\n");
			
			Hashtable<String, String> musicians;
			Enumeration<String> k;
			// TODO: clean up the way we assign musician code
			musicians = (Hashtable)$3.obj;
			k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  app_code = app_code.concat("\t\tMusician " + k
ey + " = new Musician_" + key + "();\n");
			  }
			
			app_code = app_code.concat(
"		// Set the manager up with the input file, the Conductor, and th
e Musician(s)\n" +
"		if( args.length < 1 ) {\n" +
"			System.out.println(\"Warning: No input source supplied!\
");\n" +
"		}\n" +
"		else {\n" +
"			String inputname = args[0];\n" +
"			if( !manager.SetInputSource(inputname) ) {\n" +
"				System.out.printf(\"Error: Could not open source
:%s\", inputname);\n" +
"			}\n" +
"		}\n" +
"\n" +			
"		manager.SetJMusicWrapper(new JMusicWrapper());\n" +
"		manager.SetTempoOptions(tempoOptions);\n" +
"		manager.SetConductor(conductor);\n" +
"\n" +				
"		// We're going to need to have an individual AddMusician call fo
r each Musician\n");
			
			k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  app_code = app_code.concat("\t\tmanager.AddMus
ician(" + key + ");\n");
			  }

			  app_code = app_code.concat(
"		// Note, if we're writing the output to a MIDI file on disk we m
ight want to have a way of\n" +
"		// providing an output file name.\n" +

"		try {\n" +
"		manager.MakeSomeMusic();\n" +
"		} catch (Exception e) {\n" +
"		};\n" +
"	}\n" +
"}\n\n");

			app_code = app_code.concat($1.code);
			
			String conductor_code = new String($2.code);

			//System.out.println(">>>>>>>>>>>>> CompiledUpbeatApplic
ation.java >>>>>>>>>>>>>>>>>\n\n" + app_code +
			//		"\n>>>>>>>>>>>>> CompiledConductor.java 
>>>>>>>>>>>>>>>>>\n\n" + conductor_code);
			k = musicians.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
			//	System.out.println(">>>>>>>>>>>>> Musician_" + k
ey + ".java >>>>>>>>>>>>>>>>>\n\n" + musicians.get(key) + "\n\n");
			}
			/* 1. Construct CompiledUpbeatApplication:
			 * 	a. iterate through musicians by NAME and constru
ct Musician NAME = new Musician_NAME()
			 * 	b. also iterate through and do manager.addMusici
an(NAME);
			 *  c. stick the tempo options on the end!
			 * 2. Construct CompiledConductor
			 *  a. stick in 
			 */
			if(current_symbol_table.numSymbols() > 0) {
				System.err.println("Warning: global symbol table
 has symbols; this is unusual in Upbeat:\n" + current_symbol_table.toString());
			}
			$$ = new upbeatVal(app_code);
			$$.sval = conductor_code;
			$$.obj = new Hashtable<String, String>();
			k = musicians.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
				((Hashtable<String,String>)$$.obj).put(key, musi
cians.get(key));
			}
    	}
    ;
 
header
    : header_time_sig header_tempo
    	{ $$ = new upbeatVal("class CompiledTempoOptions extends TempoOptions {\
n" +
    	"\tCompiledTempoOptions(){\n\t\t// This is where and how we set the head
er information\n" +
    	$1.code + $2.code +
    	"\t}\n}\n"); }
	| header_tempo header_time_sig
		{ $$ = new upbeatVal("class CompiledTempoOptions extends TempoOp
tions {\n" +
	    "\tCompiledTempoOptions(){\n\t\t// This is where and how we set the 
header information\n" +
	    $2.code + $1.code +
	    "\t}\n}\n"); }
    ;
 
header_time_sig
    : TIME_SIGNATURE CONSTANT '/' CONSTANT ';'
    	{ $$ = new upbeatVal("\t\tsuper.TIME_SIGNATURE_TOP = " + $2.ival +
    						 ";\n\t\tsuper.TIME_SIGNATURE_BO
TTOM = " + $4.ival + ";\n"); }
    ;
 
header_tempo
    : TEMPO CONSTANT ';'
    	{
    	if ($2.ival < 1 || $2.ival > 1000) {
    	//TODO: what are the legal tempo values?
    	//TODO: define a warning and an error function for parsing? lexing?
    		System.err.print("Warning: TEMPO must be an integer between 1 an
d 1000, representing beats per minute.  " +
    		"Defaulting to 100 bpm.\n");
    		$2.ival = 100;
    	}
    	$$ = new upbeatVal("\t\tsuper.TEMPO = " + $2.ival + ";\n"); }
    ;
 
conductor_block
    : CONDUCTOR '{'
    	{
    		SymbolTable t = new SymbolTable(current_symbol_table);
    		current_symbol_table = t;
    		current_symbol_table.inConductor = true;
    	}
    conductor_body '}'
    	{
    	$$ = new upbeatVal($4.code);
    	current_symbol_table = current_symbol_table.parent;
    		/* 
    		 * Write out CompiledConductor class with:
    		 * 1. Declarations for all local variables in Upbeat Conductor {
} block
    		 * 2. Constructors for CompiledConductor class that initialize a
ll local Upbeat variables
    		 * 3. All functions defined in Conductor {} block
    		 * 4. 
    		 */
    	}
    | error '}'
    {
    	System.err.println("Error in Conductor.");
    	if( current_symbol_table != null )
    		current_symbol_table = current_symbol_table.parent;
    }
    ;
 
conductor_body
    : function_definition_list
    {
    	String declarations = new String("");
    	// there are no declarations
    	String statements = new String("");
    	// there are no statements
    	String functions = new String("");
    	functions = functions.concat($1.code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	$$ = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
    | statement_list function_definition_list
    {
    	String declarations = new String("");
    	// there are no declarations
    	String statements = new String($1.code);
    	String functions = new String("");
    	functions = functions.concat($2.code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	$$ = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
    | declaration_list function_definition_list  
    {
    	String declarations = new String($1.code);
    	String statements = new String("");
    	// there are no statements
    	String functions = new String($2.code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	$$ = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }  
    | declaration_list statement_list function_definition_list
    {
    	String declarations = new String($1.code);
    	String statements = new String($2.code);
    	String functions = new String($3.code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	$$ = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
    | error '}'
    {
    	System.err.println("Error in Conductor body.");
    }
    | error STRING_LITERAL
    {
    	System.err.println("Error in Conductor body.  Missing closing } perhaps?
");
    }
    ; 
 
compound_statement
    : '{' '}'
    	{
    		$$ = new upbeatVal("{ }");
    	}
    | '{' statement_list '}'
    	{
    		// No Symbol table needed, since there are no declarations.
    		$$ = new upbeatVal("{\n" + $2.code + " }\n");
    	}
    | '{' 
		{ // start new symbol table:
    		//  1. create new symbol table new_table
    		//  2. assign current_sym_table to be its parent
    		//  3. assign new_table to current_sym_table
  			SymbolTable t = new SymbolTable(current_symbol_table);
  			current_symbol_table = t;
		}
    declaration_list statement_list '}'
    	{
    		$$ = new upbeatVal("{\n" + $3.code + "\n" + $4.code + " }\n");
    	  	current_symbol_table = current_symbol_table.parent;
    	}
    ;
 
statement_list
    : statement
    {
    	$$ = new upbeatVal($1.code);
    }
    | statement_list statement
    {
    	$$ = new upbeatVal($1.code + $2.code);
    }
    ;
 
statement
    : compound_statement
    	{
    		$$ = new upbeatVal($1.code);
    	}
    | expression_statement
		{
    		$$ = new upbeatVal($1.code);
		}
    | adding_cue_statement
		{
    		$$ = new upbeatVal($1.code);
		}
    | musical_statement
		{
    		$$ = new upbeatVal($1.code);
		}
    | flow_control_statement
		{
    		$$ = new upbeatVal($1.code);
		}
    | error ';'
    {
    	System.err.println("Error in statement.");
    }
    ;

flow_control_statement
    : case_statement
    | repeat_statement
    | return_statement
    | continue_statement
    | break_statement
    ;

continue_statement
	: CONTINUE ';'
		{
	    	if( !current_symbol_table.inRepeat )
	    		yyerror("Continue statement outside of a Repeat statemen
t");
	    	
	    	$$ = new upbeatVal("continue;\n");
		}
    ;
    
break_statement
	: BREAK ';'
		{
	    	if( !current_symbol_table.inRepeat )
	    		yyerror("Break statement outside of a Repeat statement")
;
	    	
	    	$$ = new upbeatVal("break;\n");
		}
    ;
    
return_statement
    : RETURN ';'
    	{
    		if( !current_symbol_table.inConductorFunc )
    			yyerror("Return statement outside of a function definiti
on");
    		else {
    			if( current_symbol_table.GetCurrentReturnType() != upbea
tVal.Type.ubVOID )
	    			yyerror("Function " + current_symbol_table.myNam
e + " requires a return value" );
	    		
    			current_symbol_table.Returns();
    		}
    		$$ = new upbeatVal("return;\n");
    	}
    | RETURN expression ';'
    	{
    		if( !current_symbol_table.inConductorFunc ) {
    			yyerror("Return statement outside of a function definiti
on");
    			// this is a dummy for now
    			$$ = new upbeatVal("return;\n");
    		}
    		else {
	    		$$ = new upbeatVal("return " + perform_cast( $2.type, cu
rrent_symbol_table.GetCurrentReturnType() ) + $2.code + ";\n");
	    		current_symbol_table.Returns();
    		}
    	}
    ;
 
expression_statement
    : expression ';'
    	{
    		$$ = new upbeatVal($1.code + ";\n");
    	}
    | ';'
    	{
    		$$ = new upbeatVal(";\n");
    	}
    ;
 
case_statement
    : CASE 
	    {
    		if( !current_symbol_table.inConductorFunc 
       		 && !current_symbol_table.inCueResponse )
       			yyerror("Case statement outside a function definition or
 cue response");
	    }
    '{' case_list '}'
	    {
	    	$$ = new upbeatVal( $4.code );
	    }
    | CASE
	    {
	    	if( !current_symbol_table.inConductorFunc 
	       	&& !current_symbol_table.inCueResponse )
	       		yyerror("Case statement outside a function definition or
 cue response");
	    }
		case
	    {
	    	$$ = new upbeatVal( $3.code );
	    }
    ;
 
case_list
    : case
    	{
    		$$ = new upbeatVal($1.code);
    	}
    | case case_list
	    {
	    	String newCode = new String("");
	    	newCode = newCode.concat( $1.code );
	    	newCode = newCode.concat( "else " );
	    	newCode = newCode.concat( $2.code );
	    	
	    	$$ = new upbeatVal( newCode );
	    }
    ;
 
case
    : '(' expression ')' statement
	    {
	    	String newCode = new String("if(");
	    	newCode = newCode.concat($2.code);
	    	newCode = newCode.concat(") {\n");
	    	newCode = newCode.concat( $4.code );
	    	newCode = newCode.concat( "}\n" );
	    	
	    	$$ = new upbeatVal( newCode );
	    }
    ;

repeat_statement
    : REPEAT '(' expression ')'   
	{
    	if( !current_symbol_table.inConductorFunc 
          	&& !current_symbol_table.inCueResponse )
          	yyerror("Repeat statement outside a function definition or cue r
esponse");
		if ($3.type == upbeatVal.Type.ubBOOL) {
			String newCode = new String ("while (");
			newCode = newCode.concat ($3.code);
			newCode = newCode.concat (") {\n");
			$$ = new upbeatVal( newCode );
    	}
		else {
			String ub_REPEATlimit = new String( getNextTempName() );
 // need to get the name to use later
			String newCode = new String("int " + ub_REPEATlimit + " 
= " + perform_cast($3.type, upbeatVal.Type.ubINT) + $3.code  + ";\n");
			// now generate for loop
    		newCode = newCode.concat ("for (int ub_REPEATscroll = 1; ub_REPE
ATscroll <= " + ub_REPEATlimit + "; ub_REPEATscroll++ ) {\n");
    		$$ = new upbeatVal( newCode );
		}
		
		SymbolTable t = new SymbolTable(current_symbol_table);
		t.inRepeat = true;
		current_symbol_table = t;
	}
    statement 
    {
    	$$ = new upbeatVal( $5.code + $6.code + " }\n" );
    	
    	// We need to reset the symbol table
    	current_symbol_table = current_symbol_table.parent;
    }
    ;

// Expressions
expression
    : logical_or_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | postfix_expression EQ_ASS expression
      	{
    		if( !$1.assignable ) {
    			yyerror("Cannot assign to expression to left of =");
    			if( $1.code != null && $1.code.charAt(0) == '(' && $1.co
de.charAt($1.code.length() - 1) == ')' )
    				yyerror("If it is parenthesized, try removing th
e parentheses");
    		}

    		// If we haven't checked to make sure we've defined the stuff us
ed in the
    		// post fix expression, we need to do the check now!
    		if( !$1.definitionCheck ) {
    			if( current_symbol_table.GetDefLine( $1.sval ) == -1 ) {
    				yyerror("Identifier: " + $1.sval + " is undefine
d");
    				if($1.sval.toLowerCase().equals("return")) {
    					yyerror("Perhaps you meant \"Return\" wi
th a capital \"R\"?");
    				} else if ($1.sval.toLowerCase().equals("input")
) {
    					yyerror("Perhaps you meant \"input\", al
l lowercase?");
    				} // else no help
    			}
    		}

			$$ = apply_op("=", $1.code, $3.code, $1.type, $3.type);
			/* TODO: (optional) mark in symbol table that it's been 
assigned */
      	}
    ;
 
constant_expression
    : logical_or_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    ;
    
logical_or_expression
    : logical_and_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | logical_or_expression OR_OP logical_and_expression
	    {
			$$ = apply_op("||", $1.code, $3.code, $1.type, $3.type);
	  	}
    ;
 
logical_and_expression
    : equality_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | logical_and_expression AND_OP equality_expression
	    {
			$$ = apply_op("&&", $1.code, $3.code, $1.type, $3.type);
	  	}
    ;
    
equality_expression
    : relational_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | equality_expression EQ_OP relational_expression
	    {
			$$ = apply_op("==", $1.code, $3.code, $1.type, $3.type);
	  	}
    | equality_expression NE_OP relational_expression
	    {
			$$ = apply_op("!=", $1.code, $3.code, $1.type, $3.type);
	  	}
    ;

relational_expression
    : range_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | relational_expression LESS_OP range_expression
	    {
			$$ = apply_op("<", $1.code, $3.code, $1.type, $3.type);
	  	}
    | relational_expression GREAT_OP range_expression
	    {
			$$ = apply_op(">", $1.code, $3.code, $1.type, $3.type);
	  	}
    | relational_expression LE_OP range_expression
	    {
			$$ = apply_op("<=", $1.code, $3.code, $1.type, $3.type);
	  	}
    | relational_expression GE_OP range_expression
	    {
			$$ = apply_op(">=", $1.code, $3.code, $1.type, $3.type);
	  	}
    ;

range_expression
    : additive_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | additive_expression IN range_specifier
	    {
    		if( $1.type != upbeatVal.Type.ubINT && $1.type != upbeatVal.Type
.ubFLOAT ) {
    			yyerror("Expression to left of 'in' keyword on line does
 not evaluate to an " +
    					upbeatTypeName(upbeatVal.Type.ubINT) + "
 or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT) + ".");
    		}
    		
	    	upbeatVal.Type tempType;
	    	if( $1.type == upbeatVal.Type.ubINT && 
	    	    $3.rangeLeftType == upbeatVal.Type.ubINT &&
	    	    $3.rangeRightType == upbeatVal.Type.ubINT )
	    		tempType = upbeatVal.Type.ubINT;
	    	else
	    		tempType = upbeatVal.Type.ubFLOAT;
	    	
	    	// Lets get our additive expression code right
	    	// We need to make sure to cast it if need be...
	    	String addExpr = new String("(");
	    	if( $1.type != tempType )
	    		addExpr = addExpr.concat( "(" + javaTypeName(tempType) +
 ")" );
	    	addExpr = addExpr.concat($1.code);
	    	addExpr = addExpr.concat(")");
	    	
	    	// Do the same for our right and left expressions in our
	    	// range specifier
	    	String leftExpr = new String("(");
	    	if( $3.rangeLeftType != tempType )
	    		leftExpr = leftExpr.concat( "(" + javaTypeName(tempType)
 + ")" );
	    	leftExpr = leftExpr.concat($3.rangeLeft);
	    	leftExpr = leftExpr.concat(")");
	    	
	    	String rightExpr = new String("(");
	    	if( $3.rangeRightType != tempType )
	    		rightExpr = rightExpr.concat( "(" + javaTypeName(tempTyp
e) + ")" );
	    	rightExpr = rightExpr.concat($3.rangeRight);
	    	rightExpr = rightExpr.concat(")");
	    	
	    	// Finally, we need to make sure our operations are correct
	    	// depending on whether the range is open or closed.
	    	String leftOp;
	    	if( $3.leftOpen )
	    		leftOp = new String(" > ");
	    	else
	    		leftOp = new String(" >= ");
	    	
	    	String rightOp;
	    	if( $3.rightOpen )
	    		rightOp = new String(" < ");
	    	else
	    		rightOp = new String(" <= ");
	    	
	    	String newCode = new String("((");
	    	newCode = newCode.concat( addExpr + leftOp + leftExpr );
	    	newCode = newCode.concat( ") && (");
	    	newCode = newCode.concat( addExpr + rightOp + rightExpr );
	    	newCode = newCode.concat("))");
	    	
	    	$$ = new upbeatVal(newCode);
	    	$$.type = upbeatVal.Type.ubBOOL;
	    }
    ;

range_specifier
    : '(' expression ',' expression ')'
	    {
	    	if( $2.type != upbeatVal.Type.ubINT && 
	    		$2.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( $4.type != upbeatVal.Type.ubINT && 
	    		$4.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	$$ = new upbeatVal();
	    	$$.rangeLeft = new String( $2.code );
	    	$$.rangeRight = new String( $4.code );
	    	$$.leftOpen = true;
	    	$$.rightOpen = true;
	    	$$.rangeLeftType = $2.type;
	    	$$.rangeRightType = $4.type;
	    }
    | '[' expression ',' expression ')'
	    {
	    	if( $2.type != upbeatVal.Type.ubINT && 
	    		$2.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( $4.type != upbeatVal.Type.ubINT && 
	    		$4.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	$$ = new upbeatVal();
	    	$$.rangeLeft = new String( $2.code );
	    	$$.rangeRight = new String( $4.code );
	    	$$.leftOpen = false;
	    	$$.rightOpen = true;
	    	$$.rangeLeftType = $2.type;
	    	$$.rangeRightType = $4.type;
	    }
    | '(' expression ',' expression ']'
	    {
	    	if( $2.type != upbeatVal.Type.ubINT && 
	    		$2.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( $4.type != upbeatVal.Type.ubINT && 
	    		$4.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	$$ = new upbeatVal();
	    	$$.rangeLeft = new String( $2.code );
	    	$$.rangeRight = new String( $4.code );
	    	$$.leftOpen = true;
	    	$$.rightOpen = false;
	    	$$.rangeLeftType = $2.type;
	    	$$.rangeRightType = $4.type;
	    }
    | '[' expression ',' expression ']'
	    {
	    	if( $2.type != upbeatVal.Type.ubINT && 
	    		$2.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( $4.type != upbeatVal.Type.ubINT && 
	    		$4.type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	$$ = new upbeatVal();
	    	$$.rangeLeft = new String( $2.code );
	    	$$.rangeRight = new String( $4.code );
	    	$$.leftOpen = false;
	    	$$.rightOpen = false;
	    	$$.rangeLeftType = $2.type;
	    	$$.rangeRightType = $4.type;
	    }
    ;
 
additive_expression
    : multiplication_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | additive_expression '+' multiplication_expression
    	{
    		$$ = apply_op("+", $1.code, $3.code, $1.type, $3.type);
    	}	
    | additive_expression '-' multiplication_expression
	    {
	    	$$ = apply_op("-", $1.code, $3.code, $1.type, $3.type);
	    }
    ;
 
multiplication_expression
    : cast_expression
		{
			$$ = new upbeatVal( $1.code );
			$$.type = $1.type;
		}
    | multiplication_expression '*' cast_expression
	    {
	    	$$ = apply_op("*", $1.code, $3.code, $1.type, $3.type);
	    }
    | multiplication_expression '/' cast_expression
	    {
    		$$ = apply_op("/", $1.code, $3.code, $1.type, $3.type);
	    }
    | multiplication_expression '%' cast_expression
	    {
			$$ = apply_op("%", $1.code, $3.code, $1.type, $3.type);
	    }
    ;

cast_expression
    : postfix_expression
    	{
    		$$ = new upbeatVal( $1.code );
    		$$.type = $1.type;
    		
    		// If we haven't checked to make sure we've defined the stuff us
ed in the
    		// post fix expression, we need to do the check now!
    		if( !$1.definitionCheck ) {
    			if( current_symbol_table.GetDefLine( $1.sval ) == -1 ) {
    				yyerror("Identifier: " + $1.sval + " is undefine
d");
    				if($1.sval.toLowerCase().equals("return")) {
    					yyerror("Perhaps you meant \"Return\" wi
th a capital \"R\"?");
    				} else if ($1.sval.toLowerCase().equals("input")
) {
    					yyerror("Perhaps you meant \"input\", al
l lowercase?");
    				} // else no help
    			}
    		}
    			
    	}
    | unary_operator cast_expression
	    {
	    	$$ = new upbeatVal( $1.code + $2.code );
	    	$$.type = $2.type;
	    	
	    	switch( $1.unaryOp ) {
	    	case uopPLUS:
	    		switch( $2.type ) {
	    		case ubVOID:
	    		case ubBOOL:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '+' 
to an expression of type: "
	    					+ upbeatTypeName($2.type));
	    		}
	    		break;
	    	case uopMINUS:
	    		switch( $2.type ) {
	    		case ubVOID:
	    		case ubBOOL:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '-' 
to an expression of type: "
	    					+ upbeatTypeName($2.type));
	    		}
	    		break;
	    	case uopNOT:
	    		switch( $2.type ) {
	    		case ubVOID:
	    		case ubINT:
	    		case ubFLOAT:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubTIME:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '!' 
to an expression of type: "
	    					+ upbeatTypeName($2.type));
	    		}
	    		break;
	    	}
	    }
    | '(' type_specifier ')' cast_expression
	    {
    		String newCode = new String( force_cast($4.type, $2.type) );
    		newCode = newCode.concat( $4.code );
	    	$$ = new upbeatVal(newCode);
	    	$$.type = $2.type;
	    }
    ;
 
    // These guys will be tricky because we need to create a symbol table
    // for function definitions so we can lookup their return types here.
    // Otherwise, our type tracking will get all screwed up.
    // Since YACC reads the source from top to bottom, we might need to
    // force the programmers to write their member functions above where
    // they're called.
postfix_expression
    : primary_expression
    	{
    		$$ = new upbeatVal( $1.code );
    		$$.type = $1.type;
    		$$.sval = $1.sval;
    		$$.alreadyPostFixed = false;
    		
    		// Up the line we might need to do a definition check
    		$$.definitionCheck = $1.definitionCheck;
    		$$.assignable = $1.assignable;
    	}
    | input_expression
	    {
	    	$$ = new upbeatVal( $1.code );
	    	$$.type = $1.type;
	    	
	    	// Don't think we need this here
	    	//$$.sval = $1.sval;
	    	
	    	// We never want to add a postfix operator after an input expres
sion
	    	$$.alreadyPostFixed = true;
	    	$$.definitionCheck = true;
	    	$$.assignable = false;
	    }
    | postfix_expression '(' ')'
	    {
	    	if( $1.alreadyPostFixed )
				yyerror("Chaining of postfix expressions not all
owed");
		    
		    // Now let's do the type checking!
			if( current_symbol_table.GetFuncDefLine( $1.sval ) == -1
 ) {
				yyerror("Function: " + $1.sval + " is undefined"
);
				$$ = $1;
			}
			else
				$$ = CreateFunctionCall( $1 );
			
			
			$$.alreadyPostFixed = true;
			$$.definitionCheck = true;
			$$.assignable = false;
	    }
    | postfix_expression '(' argument_expression_list ')'
	    {
	    	if( $1.alreadyPostFixed )
				yyerror("Chaining of postfix expressions not all
owed");

	    	// Now let's do the type checking!
			if( current_symbol_table.GetFuncDefLine( $1.sval ) == -1
 ) {
				yyerror("Function: " + $1.sval + " is undefined"
);
				$$ = $1;
			}
			else
				$$ = CreateFunctionCall( $1, $3 );
			
			$$.alreadyPostFixed = true;
	    	$$.definitionCheck = true;
	    	$$.assignable = false;
	    }
    | postfix_expression '.' DATA
	    {
    		if( $1.type != upbeatVal.Type.ubCUE ) {
    			yyerror("Expression must be of type " + upbeatTypeName(u
pbeatVal.Type.ubCUE) + " to have a data member");
    		}
	    	$$ = new upbeatVal( $1.code + ".data" );
	    	$$.type = upbeatVal.Type.ubINT;
	    	$$.alreadyPostFixed = true;
	    	// Now let's do the type checking!
	    	if( !$1.definitionCheck ) {
				if( current_symbol_table.GetDefLine( $1.sval ) =
= -1 ) {
					yyerror("Using " + $1.sval + " without h
aving declared it");
				}
	    	}
			$$.sval = $1.sval;
	    	$$.definitionCheck = true;
	    	$$.assignable = true;
	    }
    ;
    
input_expression
	: INPUT '.' VALUE_AT '(' expression ')'
		{
    		if( !current_symbol_table.inConductorFunc ) {
    			yyerror( "Attempting to use reserved word input while no
t in a Conductor function" );
    		}
			String newCode = new String("");
			newCode = newCode.concat($1.code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("ValueAt(");
			newCode = newCode.concat( perform_cast($5.type, upbeatVa
l.Type.ubINT) );
			newCode = newCode.concat( $5.code );
			newCode = newCode.concat(")");
			
			if( $5.type != upbeatVal.Type.ubINT && $5.type != upbeat
Val.Type.ubTIME ) {
				yyerror(" Expression:\n" + $5.code + "\nmust be 
either of type " + upbeatTypeName(upbeatVal.Type.ubINT) + " or "
						+ upbeatTypeName(upbeatVal.Type.
ubTIME));
			}
			
			$$ = new upbeatVal( newCode );
			$$.type = upbeatVal.Type.ubFLOAT;
		}
    | INPUT '.' CURRENT_VALUE
		{
    		if( !current_symbol_table.inConductorFunc ) {
				yyerror( "Attempting to use reserved word input 
while not in a Conductor function" );
			}
	    	String newCode = new String("");
			newCode = newCode.concat($1.code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("CurrentValue()");
			$$ = new upbeatVal( newCode );
			$$.type = upbeatVal.Type.ubFLOAT;
		}
    | INPUT '.' MORE
		{
    		if( !current_symbol_table.inConductorFunc ) {
				yyerror( "Attempting to use reserved word input 
while not in a Conductor function" );
			}
	    	String newCode = new String("");
			newCode = newCode.concat($1.code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("GetMore()");
			$$ = new upbeatVal( newCode );
			$$.type = upbeatVal.Type.ubBOOL;
		}
    ;

primary_expression
    : IDENTIFIER
    	{
    		$$ = new upbeatVal($1.code);
    		$$.sval = $1.sval;
    		$$.type = current_symbol_table.GetType($1.sval);
    		$$.definitionCheck = false;
    		$$.assignable = true;
    	}
    | CURR_CUE
	    {
    		if( !current_symbol_table.inCueResponse ) {
    			yyerror("Attempting to use " + $1.code + " while not in 
a cue response");
    		}
    		$$ = new upbeatVal($1.code);
    		$$.sval = $1.sval;
    		$$.type = upbeatVal.Type.ubCUE;
    		$$.definitionCheck = true;
    		$$.assignable = false;
	    }
    | CONSTANT
    	{
    		$$ = new upbeatVal($1.code);
    		$$.type = $1.type;
    		$$.sval = $1.code;
    		$$.definitionCheck = true;
    		$$.assignable = false;
    	}
    | STRING_LITERAL
    	{
    		$$ = new upbeatVal($1.sval);
    		$$.sval = $1.code;
    		// Agreed, that's a little confusing.
    		$$.type = $1.type;
    		$$.definitionCheck = true;
    		$$.assignable = false;
    	}
    | '(' expression ')'
    	{
    		$$ = new upbeatVal("(" + $2.code + ")");
    		$$.type = $2.type;
    		$$.sval = $1.code;
    		$$.definitionCheck = true;
    		$$.assignable = false;
    	}
    | error ')'
	    {
	    	yyerror("Error in expression");
	    }
    ;
 
unary_operator
    : '+'
    	{
    		$$ = new upbeatVal("+");
    		$$.unaryOp = upbeatVal.UnaryOp.uopPLUS;
    	}
    | '-'
	    {
			$$ = new upbeatVal("-");
			$$.unaryOp = upbeatVal.UnaryOp.uopMINUS;
		}
    | '!'
	    {
			$$ = new upbeatVal("!");
			$$.unaryOp = upbeatVal.UnaryOp.uopNOT;
		}
    ;

argument_expression_list
	: expression
		{
    		$$ = $1;
    		$$.listTypes = new LinkedList<upbeatVal.Type>();
    		$$.listTypes.add($1.type);
    		$$.listExprs = new LinkedList<String>();
    		$$.listExprs.add($1.code);
    	}
	| argument_expression_list ',' expression
		{
			// We're not actually going to use this code...
			$$ = new upbeatVal( $1.code + ", " + $3.code );
			
			// We need to build up a list of expression codes and ty
pes
			// so we can do type checking and casting at the postfix
_expression
			// level of the grammar
			$$.listTypes = $1.listTypes;
			$$.listTypes.add($3.type);
			$$.listExprs = $1.listExprs;
			$$.listExprs.add($3.code);
		}
	;
  
parameter_list
	: declaration
		{
			$$ = new upbeatVal( $1.code );
			$$.listTypes = new LinkedList< upbeatVal.Type >();
			$$.listTypes.add( $1.type );
		}
	| parameter_list ',' declaration
		{
			$$ = new upbeatVal( $1.code + ", " + $3.code );
			$$.listTypes = $1.listTypes;
			$$.listTypes.add( $3.type );
		}
	;
    
    
declaration_list
    : declaration ';'
    	{
    		$$ = new upbeatVal($1.code + ";");
    	}
    | declaration_list declaration ';'
    	{
    		$$ = new upbeatVal($1.code + "\n" + $2.code + ";");
    	}
    ;
 
declaration
    : type_specifier declarator
    	{
    		// If we've got a phrase, we need to make sure we're not declari
ng it in the Conductor
    		if( $1.type == upbeatVal.Type.ubPHRASE && current_symbol_table.i
nConductor )
    			yyerror("Cannot declare phrases in Conductor block");
    		if( $1.type == upbeatVal.Type.ubCUE && current_symbol_table.inMu
sician )
    			yyerror("Cannot declare cues in Musician block");
    		
    		/* First, check if variable is declared already; if not, add to 
symbol table */
    		if(current_symbol_table.GetType($2.sval) == null) {
    			current_symbol_table.AddSymbol($2.sval, $1.type, lexer.c
urrent_line());
    		} else {
    			yyerror("Variable " + $2.sval + " already defined on lin
e " +
    					current_symbol_table.GetDefLine($2.sval)
 + " as an " +
    					current_symbol_table.GetType($2.sval));
    		}
    		
    		/* Assignment type checking and code generation */
    		if($2.obj instanceof String) {
    			// Need to do assignment
    			$$ = apply_op("=", $2.code, (String)$2.obj, $1.type, $2.
type);
    		} else {
    			$$ = new upbeatVal($2.code);
    		}
    		$$.code = $1.code + " " + $$.code;
    		$$.type = $1.type;
    	}
    ;
 
declarator
    : IDENTIFIER
    	{
    		$$ = new upbeatVal($1.code);
    		$$.sval = $1.sval;
    	}
    | IDENTIFIER EQ_ASS expression
    	{
    		/* NOTE THAT ASSIGNMENT TYPE CHECKING OCCURS UP AT DECLARATION. 
*/
    		/* TODO: (optional) mark in symbol table that it's been assigned
 */
    		$$ = new upbeatVal($3.type);
    		$$.sval = $1.sval;
    		$$.code = $1.code;
    		$$.obj = new String($3.code);
    	}
    ;

type_specifier
    : INT
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubINT);
    		$$.code = javaTypeName(upbeatVal.Type.ubINT);
    	}
    | FLOAT
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubFLOAT);
    		$$.code = javaTypeName(upbeatVal.Type.ubFLOAT);
    	}
    | BOOL
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubBOOL);
    		$$.code = javaTypeName(upbeatVal.Type.ubBOOL);
    	}
    | CUE
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubCUE);
    		$$.code = javaTypeName(upbeatVal.Type.ubCUE);
    	}
    | PHRASE
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubPHRASE);
    		$$.code = javaTypeName(upbeatVal.Type.ubPHRASE);
    	}
    | TIME
    	{
    		$$ = new upbeatVal(upbeatVal.Type.ubTIME);
    		$$.code = javaTypeName(upbeatVal.Type.ubTIME);
    	}
    ;
    
function_definition_list
	: function_definition
	{
    	$$ = new upbeatVal($1.code);
	}
	| function_definition_list function_definition
	{
		$$ = new upbeatVal($1.code + $2.code);
	}
	;
	
function_definition
	: IDENTIFIER '(' ')'
		{	
			// First, check if variable is declared already; if not,
 add to symbol table
    		if(current_symbol_table.GetFuncReturnType($1.code) == null) {
    			FunctionType fType = new FunctionType();
    			fType.SetReturnType( upbeatVal.Type.ubVOID );
    			current_symbol_table.AddFuncSymbol( $1.sval, fType, lexe
r.current_line());
    		} else {
    			yyerror("Function " + $1.sval + " already defined on lin
e " +
    					current_symbol_table.GetFuncDefLine($1.c
ode));
    		}
    		
    		SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = $1.sval;
		}
	compound_statement
		{
			String funcode = new String("\n");
    		$$ = new upbeatVal(upbeatVal.Type.ubVOID);
    		if($1.sval.equals("Conduct")) {
    			funcode = funcode.concat("protected ");
    		}
    		funcode = funcode.concat("void " + $1.code + "() " + $5.code);
    		$$.code = funcode;
    		current_symbol_table = current_symbol_table.parent;
		}
    | IDENTIFIER '('
    	{	
    		// We need a new symbol table to scope arguments to the function
.
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = $1.sval;
			
			// What follows is kind of weird.
			
			// Basically, we need to create a new symbol table that 
corresponds with the code
			// immediately inside this function call.  We want the p
arameters in the parameter_list
			// below to be scoped only to the function.  However, we
 need to know what types the parameters
			// are in order to create a symbol table entry for the f
unction itself.  Furthermore, we need
			// to have the function scoped one level above, which is
 why we call the current_symbol_table.parent.
			// Finally, though, we want the function to be callable 
from in itself, so we need to add it
			// to the symbol table before we process the compound_st
atement.  Otherwise, we wouldn't
			// be able to do recursion.
    	}
    parameter_list ')'
	    {
	    	// First, check if variable is declared already; if not, add to 
symbol table
			if(current_symbol_table.parent.GetFuncReturnType($1.code
) == null) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( upbeatVal.Type.ubVOID );
				fType.SetArgs( $4.listTypes );
				current_symbol_table.parent.AddFuncSymbol( $1.sv
al, fType, lexer.current_line());
			} else {
				yyerror("Function " + $1.sval + " already define
d on line " +
						current_symbol_table.parent.GetF
uncDefLine($1.sval));
			}
	    }
    compound_statement
    	{
    		String funcode = new String("\n");
    		$$ = new upbeatVal(upbeatVal.Type.ubVOID);
    		if($1.sval.equals("Conduct")) {
    			funcode = funcode.concat("protected ");
    		}
    		funcode = funcode.concat("void " + $1.code + "(" + $4.code + ") 
" + $7.code);
    		$$.code = funcode;
        	current_symbol_table = current_symbol_table.parent;
    	}
    | type_specifier IDENTIFIER '(' ')'
	    {
	    	// First, check if variable is declared already; if not, add to 
symbol table
			if(current_symbol_table.GetFuncReturnType($2.code) == nu
ll) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( $1.type );
				current_symbol_table.AddFuncSymbol( $2.sval, fTy
pe, lexer.current_line());
			} else {
				yyerror("Function " + $2.sval + " already define
d on line " +
						current_symbol_table.parent.GetF
uncDefLine($2.sval));
			}
			
			// We need a new symbol table to scope arguments to the 
function.
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = $2.sval;
	    }
    compound_statement
    	{
    		$$ = new upbeatVal($1.type);
    		if($2.sval.equals("Conduct")) {
    			yyerror("Conduct function should not have a return type"
);
    		}
    		$$.code = "\n" + $1.code + " " + $2.code + "() " + $6.code;
    		if( !current_symbol_table.returns ) {
    			yyerror("Function " + $2.sval + " does not return a valu
e");
    		}
    		current_symbol_table = current_symbol_table.parent;
    	}
    | type_specifier IDENTIFIER '('
    	{
			// We need a new symbol table to scope arguments to the 
function.
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = $2.sval;
    	}
    parameter_list ')'
	    {
	    	/* First, check if variable is declared already; if not, add to 
symbol table */
			if(current_symbol_table.parent.GetFuncReturnType($2.code
) == null) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( $1.type );
				fType.SetArgs( $5.listTypes );
				current_symbol_table.parent.AddFuncSymbol( $2.sv
al, fType, lexer.current_line());
			} else {
				yyerror("Function " + $2.sval + " already define
d on line " +
						current_symbol_table.parent.GetF
uncDefLine($2.sval));
			}
	    }
    compound_statement
    	{
    		$$ = new upbeatVal($1.type);
    		if($2.sval.equals("Conduct")) {
    			yyerror("Conduct function should not have a return type"
);
    		}
    		$$.code = "\n" + $1.code + " " + $2.code + "(" + $5.code + ") " 
+ $8.code;
    		if( !current_symbol_table.returns ) {
    			yyerror("Function " + $2.sval + " does not return a valu
e");
    		}
    		current_symbol_table = current_symbol_table.parent;
    	}
    ;
 
// Musical statements!
adding_cue_statement
    : ADD expression expression ';'
    {
    	// If we're trying to add a cue to the score from a Musician, it's an er
ror!
    	if( !current_symbol_table.inConductorFunc )
    		yyerror("Attempting to Add a cue outside the definition of a fun
ction in the Conductor");
    	
    	String newCode = new String("");
    	newCode = newCode.concat( "AddCueToScore( " );
    	newCode = newCode.concat( perform_cast( $2.type, upbeatVal.Type.ubCUE ) 
);
    	newCode = newCode.concat( $2.code + ", " );
    	newCode = newCode.concat( perform_cast( $3.type, upbeatVal.Type.ubTIME) 
);
    	newCode = newCode.concat($3.code + ");\n");
    	
    	$$ = new upbeatVal(newCode);
    }
    ;

musical_statement
    : phrase_expression ';' { $$ = new upbeatVal( $1.code + ";\n" ); }
    | phrase_control_expression ';' { $$ = new upbeatVal( $1.code + ";\n" ); }
    ;

phrase_control_expression
    : CHANGE change_parameter to_by_option expression
    	{
    		if( !current_symbol_table.inMusician )
    			yyerror("Must be in a Musician to Change Volume, Pitch, 
or Instrument");
    		
    		String newCode = new String("getMusicMaker().change");
    		switch ($2.changeParam ){
    		case Pitch:
    			newCode = newCode.concat("Pitch");
    			break;
    		case Volume:
    			newCode = newCode.concat("Volume");
    			break;
    		case Instrument:
    			newCode = newCode.concat("Instrument");
    			break;
    		}
    		
    		switch ($3.toOrBy ){
    		case To:
    			newCode = newCode.concat("To");
    			break;
    		case By:
    			newCode = newCode.concat("By");
    			break;
    		}
    		
    		newCode = newCode.concat("(");
    		newCode = newCode.concat( perform_cast( $4.type, upbeatVal.Type.
ubINT) );
    		newCode = newCode.concat($4.code);
    		newCode = newCode.concat(", ");
    		if(current_symbol_table.inCueResponse) {
    			newCode = newCode.concat("cue.getTime()");
    		} else {
    			newCode = newCode.concat("1");
    		}
    		newCode = newCode.concat(")");
    		$$ = new upbeatVal(newCode);
    	}
    ;

change_parameter
    : VOLUME { $$ = new upbeatVal( upbeatVal.ChangeParam.Volume ); }
    | INSTRUMENT { $$ = new upbeatVal( upbeatVal.ChangeParam.Instrument ); }
    | PITCH { $$ = new upbeatVal( upbeatVal.ChangeParam.Pitch ); }
    ;
 
to_by_option
    : TO { $$ = new upbeatVal( upbeatVal.ToBy.To ); }
    | BY { $$ = new upbeatVal( upbeatVal.ToBy.By ); }
    ;

phrase_expression
    : first_phrase continuing_phrases
    {
    	if( !current_symbol_table.inMusician )
    		yyerror("Attempting to play things outside a Musician");
    	
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat($1.code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
$1.sval));
    	
    	if ($2 != null) {
    		code = code.concat($2.code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, $2.sval));    		
    	}
    	
    	
    	code = code.concat(String.format("getMusicMaker().appendPhraseAt(%s, cue
.getTime())", tempVarName));
    	$$ = new upbeatVal(code);
    }
    ;

first_phrase
    : repeated_phrase
    | one_time_phrase
    ;

repeated_phrase
    : DB ':' musical_phrase RRPT
    	{
    		String code = new String();
    		String tempVarName = getNextTempName();
        	code = code.concat(String.format("MusicPhrase %s = new MusicPhra
se();\n", tempVarName));
        	for (String p : $3.listval) {
        		code = code.concat(String.format("%s.appendPhrase(%s);\n
", tempVarName, p));
        	}
    		code = code.concat(String.format("%s.setRepeat(-1);\n", tempVarN
ame));
    		upbeatVal res = new upbeatVal(code);
    		res.sval = tempVarName;
    		$$ = res;
    	}
    | DB ':' musical_phrase RRPT constant_expression
    	{
	    	String code = new String();
			String tempVarName = getNextTempName();
	    	code = code.concat(String.format("MusicPhrase %s = new MusicPhra
se();\n", tempVarName));
	    	for (String p : $3.listval) {
	    		code = code.concat(String.format("%s.appendPhrase(%s);\n
", tempVarName, p));
	    	}
			code = code.concat(String.format("%s.setRepeat(%s);\n", 
tempVarName, $5.code));
			upbeatVal res = new upbeatVal(code);
			res.sval = tempVarName;
			$$ = res;
    	}
    ;

one_time_phrase
    : DB musical_phrase DB
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : $2.listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		$$ = res;
    }
    ;

continuing_phrases
    : continued_repeated_phrase continuing_phrases
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat($1.code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
$1.sval));
    	
    	if ($2 != null) {
    		code = code.concat($2.code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, $2.sval));    		
    	}
    	
    	$$ = new upbeatVal(code);
    	$$.sval = tempVarName;
    }
    | continued_one_time_phrase continuing_phrases
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat($1.code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
$1.sval));
    	
    	if ($2 != null) {
    		code = code.concat($2.code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, $2.sval));    		
    	}
    	
    	$$ = new upbeatVal(code);
    	$$.sval = tempVarName;
    }
    |
    	{
    		$$ = null;
    	}
    ;

musical_phrase
    : IDENTIFIER
		{
    		if(current_symbol_table.GetType($1.sval) == null) {
    			yyerror("Using " + $1.sval + " without having declared i
t");
    		}
    		$$ = new upbeatVal("");
    		$$.sval = $1.sval;
    		$$.type = current_symbol_table.GetType($1.sval);
    		if ($$.type != upbeatVal.Type.ubPHRASE) {
    			yyerror ("Using a non-phrase variable in the musical phr
ase play statement is not allowed");
    		}
    		$$.listval = new LinkedList<String>();
    		$$.listval.add($1.code);
		}
    | IDENTIFIER '|' musical_phrase
    	{
			if(current_symbol_table.GetType($1.sval) == null) {
				yyerror("Using " + $1.sval + " without having de
clared it");
			}
			if( current_symbol_table.GetType($1.sval) != upbeatVal.T
ype.ubPHRASE ) {
				yyerror("Using a non-phrase variable in a musica
l phrase play statement is not allowed");
			}
			$$ = new upbeatVal("");
			$$.sval = $1.sval;
    		$$.type = upbeatVal.Type.ubPHRASE;
			$$.listval = new LinkedList<String>();
			$$.listval.add($1.code);
			if($3.listval != null) {
				for(String p : $3.listval) {
					$$.listval.add(p);
				}
			}
    	}
    | CONSTANT
    {
    	//NOTE: ALL constants of type "ubPHRASE" are RESTS.
    	if($1.type != upbeatVal.Type.ubPHRASE) {
    		yyerror ("Musical phrases can only contain variables of type " +
 upbeatTypeName(upbeatVal.Type.ubPHRASE) + " or RESTs");
    	}
    	$$ = new upbeatVal("");
    	$$.listval = new LinkedList<String>();
    	$$.listval.add("MusicPhrase.getREST()");
    }
    | CONSTANT '|' musical_phrase
    {
    	//NOTE: ALL constants of type "ubPHRASE" are RESTS.
    	if($1.type != upbeatVal.Type.ubPHRASE) {
    		yyerror ("Musical phrases can only contain variables of type " +
 upbeatTypeName(upbeatVal.Type.ubPHRASE) + " or RESTs");
    	}
    	$$ = new upbeatVal("");
    	$$.listval = new LinkedList<String>();
    	$$.listval.add("MusicPhrase.getREST()");
    	
    	if($3.listval != null) {
			for(String p : $3.listval) {
				$$.listval.add(p);
			}
		}
    }
    ;

continued_repeated_phrase
    : ':' musical_phrase RRPT
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : $2.listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		code = code.concat(String.format("%s.setRepeat(-1);\n", tempVarN
ame));
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		$$ = res;
    }
    | ':' musical_phrase RRPT constant_expression
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	
    	for (String p : $2.listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		code = code.concat(String.format("%s.setRepeat(%s);\n", tempVarN
ame, $4.code));
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		$$ = res;
    }
    ;

continued_one_time_phrase
    : musical_phrase DB 
    {
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : $1.listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		$$ = res;
    }
    ;

// Musician blocks
musician_blocks
    : musician_block
    	{
			Hashtable<String, String> musician_code = new Hashtable<
String, String>();
			musician_code.put($1.sval, $1.code);
    		$$ = new upbeatVal(1);
    		// TODO: clean up the way we assign musician code
    		$$.obj = musician_code;
    		// ival indicates number of musicians
    	}
    | musician_blocks musician_block
    	{
			Hashtable<String, String> musician_code = new Hashtable<
String, String>();
			Hashtable<String, String> orig;
			Enumeration<String> k;
    		// TODO: clean up the way we assign musician code
			orig = (Hashtable)$1.obj;
			k = orig.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
				if (key.equals($2.sval)) {
					yyerror ("can't have more than one music
ian with the same name");
				}
				musician_code.put(key, orig.get(key));
			}
			musician_code.put($2.sval, $2.code);
			$$ = new upbeatVal(1 + $1.ival);
			$$.obj = musician_code;
			// ival indicates number of musicians
    	}
    ;

musician_block
    : MUSICIAN STRING_LITERAL '{' 
    	{
    		SymbolTable t = new SymbolTable(current_symbol_table);
    		current_symbol_table = t;
    		current_symbol_table.inMusician = true;
    	}
    musician_body '}'
    	{
    		String gen_code = new String();
    		
    		gen_code = gen_code.concat("package upbeat.sample;\n\n" +
    				"import upbeat.Musician;\n" +
    				"import upbeat.types.Cue;\n" +
    				"import upbeat.types.MusicPhrase;\n" +
    				"\n" +
    				"public class Musician_" + $2.code + " extends M
usician {\n");
    		
    		if($5.listval != null) {
    			for(String decl : $5.listval) {
    				gen_code = gen_code.concat(decl + "\n");
    			}
    		}
    		
    		try {
    		gen_code = gen_code.concat("	public Musician_" + $2.code + "(
) {\n" +
    				" 		// Call the Parent constructor.\
n" +
    				"		super(" + getNextMusicianChannel
() + ");\n" +
    				"		// We also need a default Cue ob
ject in case we add things to the score.\n" +
    				" 		Cue cue = new Cue();\n" +
    				"		\n" + 
    				"		// Initializations.\n" +
    				"		try {\n" +
    				$5.sval +
    				"       } catch (Exception e) {\n" +
    				"			System.err.println(\"Did
 not correctly initialize Musician. \" + e +\n" +
    				"                  \"Music may sound incorrect.\
");\n" +
    				"		}\n" +
    				"	}\n" +
    				$5.code +
    				"\n}\n");
    		} catch (Error e) {
    			yyerror("Error creating next musician: " + e.getMessage(
));
    		}
    		$$ = new upbeatVal(gen_code);
    		$$.sval = $2.code; // code has name of musician
        	current_symbol_table = current_symbol_table.parent;
    	}
    ;

musician_body
    : statement_list cue_response_list
    	{
    		String newCode = new String();
    		
	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( $2.code );
	    	newCode = newCode.concat( "\n}" );
	    	
	    	$$ = new upbeatVal( newCode );
	    	$$.sval = $1.code; // statements
	    	$$.listval = null; // no declarations
    	}
    | declaration_list cue_response_list
	    {
	    	String newCode = new String();
	    	
	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( $2.code );
	    	newCode = newCode.concat( "\n}" );
	    	
	    	$$ = new upbeatVal( newCode );
	    	$$.sval = ""; // no statements
	    	$$.listval = new LinkedList<String>();
    		$$.listval.add($1.code);
	    }
    | declaration_list statement_list cue_response_list
	    {
	    	String newCode = new String();
	    	
/* A little hacky, but for musicians:
 * 1. The code field contains the entire processCue method.
 * 2. The sval field contains statements which go in the constructor
 * 3. The listval probably only contains one element which is the declarations; 
these go at the top of the class
 */

	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( $3.code );
    		newCode = newCode.concat( "\n}" );
	    	
	    	$$ = new upbeatVal( newCode );
	    	$$.sval = $2.code;
	    	$$.listval = new LinkedList<String>();
    		$$.listval.add($1.code);
	    }
    | declaration_list statement_list
    	{
    		String newCode = new String();

    		//In some cases, musicians will just want to play one thing the 
whole song, or just at the beginning of the song.  Might as well let them!
    		newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
    		// No cue responses
			newCode = newCode.concat( "\n}" );
	    	
			$$ = new upbeatVal( newCode );
			$$.sval = $2.code;
	    	$$.listval = new LinkedList<String>();
			$$.listval.add($1.code);
	    }
    ;

cue_response_list
    : cue_response
    	{
    		$$ = new upbeatVal($1.code);
    	}
    | cue_response cue_response_list
    	{
    		String newCode = new String($1.code + "\n" + $2.code + "\n");
    		$$ = new upbeatVal( newCode );
    	}
    ;

cue_response
    : STRING_LITERAL
	    {
	    	SymbolTable t = new SymbolTable(current_symbol_table);
	    	current_symbol_table = t;
	    	current_symbol_table.inCueResponse = true;
	    }
    compound_statement
    	{
    		String newCode = new String("if (cue.getName().equals(" + $1.sva
l + ") )\n" + $3.code + "\n");
    		$$ = new upbeatVal( newCode );
    		
    		current_symbol_table = current_symbol_table.parent;
    	}
    ;

%%
  // *******************************************
  // JAVA CODE THAT IS ADDED TO THE PARSER CLASS
  // *******************************************
  /* a reference to the lexer object */
  private Yylex lexer;
  private SymbolTable current_symbol_table;
  public static int yyerrors;
  public static int yywarnings;
  // Total number of errors encountered
  
  private final Hashtable<String, short[][]> optable = new Hashtable<String, sho
rt[][]>();
  private final short castTable[][];
  
  // This is appended to the end of any temporary variable names we create
  // This ensures that all temporary variables have unique names.  Also, it
  // keeps track of how many there are (if we care)
  // DO NOT USE THIS DIRECTLY!  INSTEAD CALL TempIdentifier()!
  private int tempCounter;
  
  private int TempIdentifier() {
	  tempCounter++;
	  return tempCounter;
  }
  
  /* interface to the lexer */
  private int yylex () {
    int yyl_return = -1;
    try {
      yyl_return = lexer.yylex();
    }
    catch (IOException e) {
      System.err.println("IO error :"+e);
    }
    return yyl_return;
  }

  /* error reporting */
  public void yyerror (String error) {
    System.err.println ("Error: " + error + " at " + lexer.lexer_loc());
    yyerrors++;
  }
  
  /* warning reporting */
  public void yywarning (String warning) {
	  System.err.println("Warning: " + warning + " at " + lexer.lexer_loc())
;
	  yywarnings++;
  }

  /* lexer is created in the constructor */
  public parser(Reader r) {
    lexer = new Yylex(r, this);
    yyerrors = 0;
    yywarnings = 0;
    current_symbol_table = new SymbolTable();
    	// since we have no args, the parent is void, and it's a special top-lev
el (global) symboltable.
    
    // This is used to check to see if a cast is legal
    // Note that casting a string to a string is illegal
    // This is because we don't have an actual keyword for string types
    /*
     * 0. Not allowed.  Give an error
     * 1. Allowed, but give a warning
     * 2. Allowed, perform cast and don't give any message
     * 3. Allowed, and no cast needed
     */
    castTable = new short[][]{
    	/* from/to	  ubVOID, ubINT, ubFLOAT, ubBOOL, ubCUE, ubPHRASE,ubTIME
,ubSTRING */
    	/*ubVOID*/ 	{   3, 		0,		0,		0,	
	0,		0,		0,		0	},
        /*ubINT*/	{   0,		3,		2,		0,	
	0,		0,		2,		0	},
        /*ubFLOAT*/	{   0,		1,		3,		0,	
	0,		0,		1,		0	},
        /*ubBOOL*/	{   0,		0,		0,		3,	
	0,		0,		0,		0	},
        /*ubCUE*/	{   0,		0,		0,		0,	
	3,		0,		0,		0	},
        /*ubPHRASE*/{   0,		0,		0,		0,	
	0,		3,		0,		0	},
        /*ubTIME*/	{   0,		2,		1,		0,	
	0,		0,		3,		0	},
        /*ubSTRING*/{   0,		0,		0,		0,	
	0,		0,		0,		0	}
    };
  
    /*
     * 0. Not allowed
     * 1. Allowed; use both arguments as-is; result type is the same.
     * 2. Allowed; use both arguments as-is; result is java bool
     * 3. Special: assigning strings (rval) to CUE types (lval)
     * 4. Special: assigning strings (rval) to PHRASE types (lval)
     * 5. Special: cast right argument from java int to java String; result is l
eft type
     * 6. Special: cast left argument from java int to java String; result is ri
ght type
     * 7. Allowed: cast right argument to left type; result is left type
     * 8. Allowed: cast left argument to right type; result is right type
     * 9. Allowed: cast right argument to left type; result is bool
     * 10. Allowed: cast left argument to right type; result is bool
     */
    optable.put(new String("="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		7,		
0,		0,		0,		7,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		7,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		1,		0,		0,		3	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		1,		0,		4	},
    	/*ubTIME*/	{	0,		7,		7,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("+"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		6	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		5,		0,		0,	
	0,		0,		0,		1	}
      });
    optable.put(new String("-"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("*"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("/"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("%"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		0,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("<"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String(">"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("<="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String(">="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("=="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		0,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		0,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
2,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		2,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		2,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("!="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		0,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		0,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
2,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		2,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		2,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("&&"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("||"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });

    
    tempCounter = 0;
  }
  
  private String upbeatTypeName( upbeatVal.Type type ) {
	  switch( type ){
	  case ubVOID:
		  return "void";
	  case ubINT:
		  return "int";
	  case ubFLOAT:
		  return "float";
	  case ubBOOL:
		  return "bool";
	  case ubCUE:
		  return "cue";
	  case ubPHRASE:
		  return "phrase";
	  case ubTIME:
		  return "time";
	  case ubSTRING:
		  return "string";
	  }
	  return "Unrecognized type";
  }
  
  private String javaTypeName( upbeatVal.Type type ) {
	  switch( type ){
	  case ubVOID:
		  return "void";
	  case ubINT:
		  return "int";
	  case ubFLOAT:
		  return "double";
	  case ubBOOL:
		  return "boolean";
	  case ubCUE:
		  return "Cue";
	  case ubPHRASE:
		  return "MusicPhrase";
	  case ubTIME:
		  return "int";
	  case ubSTRING:
		  return "String";
	  }
	  return "Unrecognized type";
  }
  
  /*private boolean is_cast_allowed( upbeatVal.Type oldType, upbeatVal.Type newT
ype ) {
	  return castTable[oldType.ordinal()][newType.ordinal()];
  }*/
  
  private String force_cast( upbeatVal.Type oldType, upbeatVal.Type newType ) {

	  if( oldType == null ) {
		  throw new Error("Attempting to cast from an unknown type");
	  }
	  if( newType == null ) {
		  throw new Error("Attempting to cast to an unknown type");
	  }

	  String cast = new String("");
	  short i = castTable[oldType.ordinal()][newType.ordinal()];
	  if( i == 0 ) {
	  // Disallow cast
		  yyerror("Illegal cast from " + upbeatTypeName(oldType) + " to 
" + upbeatTypeName(newType));
		  return cast;
	  }
	  else {
		  cast = cast.concat("(" + javaTypeName(newType) + ")");
	  }
	  
	  return cast;
  }
  
  private String perform_cast( upbeatVal.Type oldType, upbeatVal.Type newType ) 
{
	  if( oldType == null ) {
		  throw new Error("Attempting to cast from an unknown type");
	  }
	  if( newType == null ) {
		  throw new Error("Attempting to cast to an unknown type");
	  }
	  
	  String cast = new String("");
	  short i = castTable[oldType.ordinal()][newType.ordinal()];
	  switch( i ) {
	  // Disallow cast
	  case 0:
		  yyerror("Illegal cast from " + upbeatTypeName(oldType) + " to 
" + upbeatTypeName(newType));
		  return cast;
	  case 1:
		  yywarning("Casting from " + upbeatTypeName(oldType) + " to " +
 upbeatTypeName(newType));
	  case 2:
		  cast = cast.concat("(" + javaTypeName(newType) + ")");
		  return cast;
	  case 3:
		  return cast;
	  default:
		  throw new Error("Received illegal cast table value.");
	  }
  }
  
  // This is just a dummy function used for convenience...
  private upbeatVal CreateFunctionCall( upbeatVal funcName ) {
	  upbeatVal temp = new upbeatVal();
	  temp.listTypes = new LinkedList< upbeatVal.Type >();
	  temp.listExprs = new LinkedList< String >();
	  return CreateFunctionCall( funcName, temp );
  }
  
  private upbeatVal CreateFunctionCall( upbeatVal funcName, upbeatVal args ) {
	  
	  LinkedList< upbeatVal.Type > paramTypes = current_symbol_table.GetPara
mTypes( funcName.sval );
	  LinkedList< upbeatVal.Type > argTypes = args.listTypes;
	  LinkedList< String > argExprs = args.listExprs;
	  
	  Iterator< upbeatVal.Type > paramIter = paramTypes.iterator();
	  Iterator< upbeatVal.Type > argIter = argTypes.iterator();
	  Iterator< String > exprIter = argExprs.iterator();
	  
	  String newCode = funcName.code;
	  newCode = newCode.concat("(");
	  
	  while( paramIter.hasNext() && argIter.hasNext() && exprIter.hasNext() 
) {
		  upbeatVal.Type argType = argIter.next();
		  upbeatVal.Type paramType = paramIter.next();
		  String expr = exprIter.next();
		  // If the argument and parameter have the same types, we don't
 need to cast
		  if( argType == paramType ) {
			  newCode = newCode.concat( expr );
		  }
		  else {
			  newCode = newCode.concat( perform_cast( argType, param
Type ) );
			  newCode = newCode.concat(expr);
		  }
			  
		  // If we still have more to go, we need to add in the commas!
		  if( paramIter.hasNext() || argIter.hasNext() || exprIter.hasNe
xt() )
			  newCode = newCode.concat(", ");
	  }
	  
	  if( paramIter.hasNext() || argIter.hasNext() || exprIter.hasNext() ) {
		  yyerror("Call to function " + funcName.code + " has incorrect 
number of arguments");
	  }
	  
	  newCode = newCode.concat(")");
	  
	  upbeatVal ret = new upbeatVal(newCode);
	  ret.type = current_symbol_table.GetFuncReturnType( funcName.sval );
	  
	  return ret;
  }
  
  private upbeatVal apply_op (String op, String lcode, String rcode, 
		  upbeatVal.Type ltype, upbeatVal.Type rtype) {
	  upbeatVal p = new upbeatVal();
	  if(op == null) {
		  throw new Error("attempt to apply unknown operator");
	  }
	  if(lcode == null || rcode == null) {
		  throw new Error("attempt to apply operator " + op + " with cod
e missing");
	  }
	  if(ltype == null || rtype == null) {
		  throw new Error("attempt to apply operator " + op + " with cod
e missing");
	  }
	  short i = optable.get(op)[ltype.ordinal()][rtype.ordinal()];
	  switch(i) {
	  case 0:
		  yyerror("Operation " + op + " not allowed on type " + upbeatTy
peName(ltype) + " (left) and " +
				  upbeatTypeName(rtype) + " (right)");
		  break;
	  case 1:
		  p.code = lcode + " " + op + " " + rcode;
		  p.type = ltype;
		  break;
	  case 2:
		  p.code = lcode + " " + op + " " + rcode;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  case 3:
		  p.code = lcode + " = new " + javaTypeName(upbeatVal.Type.ubCUE
) + "(" + rcode + ")";
		  p.type = upbeatVal.Type.ubCUE;
		  break;
	  case 4:
		  p.code = lcode + " = new " + javaTypeName(upbeatVal.Type.ubPHR
ASE) + "(" + rcode + ")";
		  p.type = upbeatVal.Type.ubPHRASE;
		  break;
	  case 5:
		  p.code = lcode + " " + op + " Integer.toString(" + rcode + ")"
;
		  p.type = ltype;
		  break;
	  case 6:
		  p.code = "Integer.toString(" + lcode + ") " + op + " " + rcode
;
		  p.type = rtype;
		  break;
	  case 7:
		  p.code = lcode + " " + op + perform_cast(rtype, ltype) + rcode
;
		  p.type = ltype;
		  break;
	  case 8:
		  p.code = perform_cast(ltype, rtype) + lcode + " " + op + rcode
;
		  p.type = rtype;
		  break;
	  case 9:
		  p.code = lcode + " " + op + perform_cast(rtype, ltype) + rcode
;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  case 10:
		  p.code = perform_cast(ltype, rtype) + lcode + " " + op + rcode
;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  default:
		  yyerror("Undefined operation with given operator and types; th
is really shouldn't happen");
	  }
	  
	  // We're going to fully parenthesize our expressions.  However, we don
't want to parenthesize our
	  // assignment expressions or else we'll get code like: int (foo = 2);
	  if( !op.equals("=") )
		  p.code = "(" + p.code + ")";
	  return p;
  }

  private static long getNextTempName = 0;
  private static String getNextTempName()
  {
	  return "t_up_" + (getNextTempName++);
  }
  
  private static int musicianChannelCounter = 0;
  private static int getNextMusicianChannel() {
	  int chan = musicianChannelCounter++;
	  if(chan == 9) {
		  chan = musicianChannelCounter++;
	  }
	  if(chan > 15) {
		  throw new Error("Upbeat currently supports only 15 musicians t
o comply with MIDI restrictions");
	  }
	  return chan;
  }
  
  private String generate_conductor_code(String declarations, String statements,
 String functions) {
  	String compiled_code = new String("");
	compiled_code = compiled_code.concat(
			"package upbeat.sample;\n\n" +
			"import upbeat.Conductor;\n" +
			"import upbeat.Manager;\n" +
			"import upbeat.types.Cue;\n\n" +
			"public class CompiledConductor extends Conductor {\n" +
			" 	// Conductor member variable declarations will g
o here\n" +
			declarations +
			"\n" +
			"	CompiledConductor() {\n" +
			"		super();\n\n" +
			"		// Conductor member variable initializat
ions will go here\n" +
			statements +
			"\n" +
			"	}\n\n" +
			"	CompiledConductor( Manager man ) {\n" +
			"		super(man);\n" +
			"\n" +		
			"		// Conductor member variable initializat
ions will go here\n" +
			statements +
			"	}\n\n" +
			functions +
			"}");

	return compiled_code;
  }
  
  /* here's how we use the lexer/parser */
  public static void main(String args[]) throws IOException {
	  int parse_retval = -1;
	  parser yyparser = new parser(new FileReader(args[0]));
	  yyparser.yydebug = false;
	  
	  String destDir = "upbeat/sample/";
	  File fdestDir = new File(destDir);
	  try {
		  if(!fdestDir.exists()) {
			  fdestDir.mkdirs();
		  }
	  } catch (Exception e) {
		  System.err.println("Error creating destination directory: " + 
destDir);
	  }

	  System.out.println("Compiling Upbeat file:  " + args[0]);

	  parse_retval = yyparser.yyparse();
	  if(parse_retval == 0 && yyerrors == 0) {
		  try {
			  /* Write code files */
			  /* Application */
			  FileWriter fstream = new FileWriter(destDir + "Compile
dUpbeatApplication.java");
			  BufferedWriter out = new BufferedWriter(fstream);
			  System.out.println("Writing CompiledUpbeatApplication.
java ...");
			  out.write(yyparser.yyval.code);
			  out.close();
			  /* Conductor */
			  fstream = new FileWriter(destDir + "CompiledConductor.
java");
			  out = new BufferedWriter(fstream);
			  System.out.println("Writing CompiledConductor.java ...
");
			  out.write(yyparser.yyval.sval);
			  out.close();

			  /* Musicians */
			  Enumeration<String> k;
			  Hashtable<String, String> musicians = (Hashtable)yypar
ser.yyval.obj;
			  k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  fstream = new FileWriter(destDir + "Musician_"
 + key + ".java");
				  out = new BufferedWriter(fstream);
				  System.out.println("Writing Musician_" + key +
 ".java ...");
				  out.write(musicians.get(key));
				  out.close();
			  }
		  } catch (Exception e) {
			  System.err.println("Error in writing out code: " + e);
		  }
		  System.out.println("Successful parse with " + yyerrors + " err
ors and " + yywarnings + " warnings!\n Resulting code written to: " + fdestDir.g
etAbsolutePath() );
	  } else {
		  System.out.print("Parse error.  Returned " + parse_retval + " 
with " + yyerrors + " errors and " + yywarnings + " warnings.\n");
	  }
	  
	  System.exit(yyerrors);
  }




Filename: Frontend//lexer_parser_src/upbeat.flex
Author: Peyton, Adrian, Matt, Fan
package upbeat.frontend;
%%

%byaccj
%line
%column
%class Yylex

%{
  /* store a reference to the parser object */
  private parser yyparser;

  /* constructor taking an additional parser object */
  public Yylex(java.io.Reader r, parser yyparser) {
    this(r);
    this.yyparser = yyparser;
  }
  
  /* Useful debugging function */
  public String lexer_loc() {
	  return "line " + (yyline+1) + " col " + (yycolumn+1);
  }
  
  public int current_line() {
	  // for some reason, lines are 0-indexed!
	  return yyline+1;
  }
  
  private String bad_code(int fromhere) {
	  return new String( zzBuffer, zzStartRead, fromhere-zzStartRead );
  }
%}

/* REGULAR DEFINITIONS */
/* useful stuff */
lineterm =	\r|\n|\r\n
inchar =	[^\r\n]
delim =		{lineterm}|[ \t\f]
ws =		{delim}+
letter =	[A-Za-z]
digit =		[0-9]

/* comments */
comment = {TraditionalComment} | {EndOfLineComment}

TraditionalComment   = "/*" ~"*/"
EndOfLineComment     = "//" {inchar}* {lineterm}


/* tokens */
id =		{letter}({letter}|{digit})* | \$ 
int =		{digit}+
float =		{digit}+(\.{digit}+)
bool =		(TRUE|FALSE)
time =		@m{digit}+
string =	\"({letter}|{digit}|[ \._\/\\~\-])*\"

/* more useful stuff */
number =	{int}|{float}

%%

/* Whitespace, statement markers */
{ws}	{ /* do nothing */ }
{comment}	{ /* comment */ }
;		{ if (yyparser.yydebug) {
			System.out.print ("\n");
		  }
		  return yycharat(0); /* end of statement */
		}

/* Single Characters */
\{		{ return yycharat(0); }
\}		{ return yycharat(0); }
\(		{ return yycharat(0); }
\)		{ return yycharat(0); }
\[		{ return yycharat(0); }
\]		{ return yycharat(0); }
\=		{ return parser.EQ_ASS; }
\:		{ return yycharat(0); }
\|		{ return yycharat(0); }
\+		{ return yycharat(0); }
\-		{ return yycharat(0); }
\*		{ return yycharat(0); }
\/		{ return yycharat(0); }
\%		{ return yycharat(0); }
\.		{ return yycharat(0); }
\,		{ return yycharat(0); }
\!		{ return yycharat(0); }
/*\$		{ return yycharat(0); }*/
"<"			{ return parser.LESS_OP; }
">"			{ return parser.GREAT_OP; }

/* Operators, logic */
"<="		{ return parser.LE_OP; }
">="		{ return parser.GE_OP; }
"=="		{ return parser.EQ_OP; }
"!="		{ return parser.NE_OP; }
"and"		{ return parser.AND_OP; }
"or"		{ return parser.OR_OP; }
"in"		{ return parser.IN; }

/* Musical phrase demarcation */
"||"		{ return parser.DB; }
/*"||:"		{ return parser.LRPT; }*/
":||"		{ return parser.RRPT; }

/* Header tokens */
TIME_SIGNATURE	{ 
			if (yyparser.yydebug) {
				System.out.print("Found a TIME_SIGNATURE\n");
			}
			yyparser.yylval = new upbeatVal(4.0);
			return parser.TIME_SIGNATURE; }
TEMPO		{
			if (yyparser.yydebug) {
				System.out.print("Found a TEMPO\n");
			}
			return parser.TEMPO; }
			
/* Major code section tokens */
Add			{ return parser.ADD; }
Conductor	{ return parser.CONDUCTOR; }
Musician	{ return parser.MUSICIAN; }

/* Flow Control */
Case		{ return parser.CASE; }
Return		{ return parser.RETURN; }
Repeat		{ return parser.REPEAT; }
Break		{ return parser.BREAK; }
Continue	{ return parser.CONTINUE; }

/* Data Input accessors */
currentValue	{ return parser.CURRENT_VALUE; }
data		{ return parser.DATA; }
more		{ return parser.MORE; }
valueAt		{ return parser.VALUE_AT; }

/* Types! */
int			{ return parser.INT; }
float		{ return parser.FLOAT; }
bool		{ return parser.BOOL; }
cue			{ return parser.CUE; }
phrase		{ return parser.PHRASE; }
time		{ return parser.TIME; }

/* Special Identifiers */
"input"		{
	yyparser.yylval = new upbeatVal("input");
	return parser.INPUT; }
\$			{ 
	yyparser.yylval = new upbeatVal("cue");
	yyparser.yylval.type = upbeatVal.Type.ubCUE;
	yyparser.yylval.sval = "$";
	return parser.CURR_CUE; }


/* Musical operations */
Change		{ return parser.CHANGE; }
Volume		{ return parser.VOLUME; }
Instrument	{ return parser.INSTRUMENT; }
Pitch		{ return parser.PITCH; }
to			{ return parser.TO; }
by			{ return parser.BY; }


/* Constants */
{int}	{ int theint = Integer.parseInt(yytext());
		  yyparser.yylval = new upbeatVal(theint);
		  yyparser.yylval.code = "" + theint;
		  yyparser.yylval.type = upbeatVal.Type.ubINT;
			return parser.CONSTANT; }
{float}	{ double thefloat = Double.parseDouble(yytext());
		  yyparser.yylval = new upbeatVal(thefloat);
		  yyparser.yylval.code = "" + thefloat;
		  yyparser.yylval.type = upbeatVal.Type.ubFLOAT;
			return parser.CONSTANT; }
{bool}	{
		if (yytext().equals("TRUE")) {
			yyparser.yylval = new upbeatVal(true);
			yyparser.yylval.code = "true";
		} else /* must be false */ {
			yyparser.yylval = new upbeatVal(false);
			yyparser.yylval.code = "false";
		}
			if (yyparser.yydebug) {
				System.out.printf("Ran across %s which is %s!\n"
, yytext(), yyparser.yylval.bval);
			}
			yyparser.yylval.type = upbeatVal.Type.ubBOOL;
			return parser.CONSTANT; }
			
{time}	{
			String numpart = yytext().substring(2);
			yyparser.yylval = new upbeatVal(Integer.parseInt(numpart
));
			yyparser.yylval.code = numpart;
			yyparser.yylval.type = upbeatVal.Type.ubTIME;
			return parser.CONSTANT;}
"REST"	{ yyparser.yylval = new upbeatVal(0);
// TODO: implement attributes for REST constant lexeme
			yyparser.yylval.type = upbeatVal.Type.ubPHRASE;
			return parser.CONSTANT;
			}

{string}	{ yyparser.yylval = new upbeatVal(yytext().substring(1, yytext()
.length()-1));
			yyparser.yylval.sval = yytext().substring(0);
			if (yyparser.yydebug) {
				System.out.printf("Got a string! %s\n", yytext()
);
			}
			yyparser.yylval.type = upbeatVal.Type.ubSTRING;
			return parser.STRING_LITERAL; }

/* Identifiers */
{id}	{
	String idname = "";
	if(yytext().equals("Conduct") || yytext().equals("currentMeasure")) {
		idname = yytext();
	} else {
		idname = "ub_zz_" + yytext();
		// for scoping, namespace will be distinct
	}
	yyparser.yylval = new upbeatVal(idname);
			// creates a new upbeatVal where the Java code equivalen
t will be the variable name
			// in a special namespace.
		  yyparser.yylval.sval = yytext();
		    // Using sval to stand for the original variable name.
// TODO: Do we need a symbol table?
			return parser.IDENTIFIER; }

/* This is a default rule to catch any code that was not going to make it. */
// TODO: Make the default lexing rule (which catches lexing errors) better.
.		{ throw new Error("Found something I shouldn't have: " + bad_cod
e(zzCurrentPosL) + " at " + lexer_loc()); }




Filename: Frontend//src/upbeat/frontend/parser.java
Author: Team
//### This file created by BYACC 1.8(/Java extension  1.15)
//### Java capabilities added 7 Jan 97, Bob Jamison
//### Updated : 27 Nov 97  -- Bob Jamison, Joe Nieten
//###           01 Jan 98  -- Bob Jamison -- fixed generic semantic constructor
//###           01 Jun 99  -- Bob Jamison -- added Runnable support
//###           06 Aug 00  -- Bob Jamison -- made state variables class-global
//###           03 Jan 01  -- Bob Jamison -- improved flags, tracing
//###           16 May 01  -- Bob Jamison -- added custom stack sizing
//###           04 Mar 02  -- Yuval Oren  -- improved java performance, added op
tions
//###           14 Mar 02  -- Tomas Hurka -- -d support, static initializer work
around
//### Please send bug reports to tom@hukatronic.cz
//### static char yysccsid[] = "@(#)yaccpar	1.8 (Berkeley) 01/20/90";



package upbeat.frontend;



//#line 2 "upbeat-a.yacc"
 /* import java.long.Math;
  import java.util.StringTokenizer; */
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;	/* Used by the symbol table*/
import java.util.LinkedList; /* Used to create phrases*/
import java.util.Iterator; /* Used to iterate over lists*/

import upbeat.frontend.upbeatVal;
  
  class upbeatVal {
	  public String code;
	  
	  public int numMusicians;
	  
	  public enum Type { ubVOID, ubINT, ubFLOAT, ubBOOL, ubCUE, ubPHRASE, ub
TIME, ubSTRING };
	  public Type type;
	  
	  public enum UnaryOp { uopPLUS, uopMINUS, uopNOT };
	  public UnaryOp unaryOp;
	  
	  public enum ToBy { To, By };
	  public ToBy toOrBy;
	  
	  public enum ChangeParam { Volume, Pitch, Instrument };
	  public ChangeParam changeParam;
	  
	  public LinkedList<String> listval;
	  
	  /* This is used to list the types in the parameter list of functions*/
	  public LinkedList< upbeatVal.Type > listTypes;
	  public LinkedList< String > listExprs;
	  
	  /* We were running into problems because we check to see if functions 
are defined at a different*/
	  /* place as regular identifiers.  As a result, I had to move the check
 to see whether an identifier*/
	  /* exists up a bit higher in the grammar.  As a result, we now have th
is value that tells whether*/
	  /* or not we need to do a definition check.*/
	  public boolean definitionCheck;
	  
	  public int ival;
	  public double dval;
	  public boolean bval;
	  public String sval;
	  public Object obj;
	  
	  /* These are used in range expressions.  rangeLeft and rangeRight*/
	  /* are the strings corresponding with the expressions, and*/
	  /* leftOpen and rightOpen tell whether the interval is open on the*/
	  /* left and right*/
	  public String rangeLeft;
	  public boolean leftOpen;
	  public Type rangeLeftType;
	  public String rangeRight;
	  public boolean rightOpen;
	  public Type rangeRightType;
	  
	  /* This is used in the postfix_expression productions*/
	  /* so we can signal errors when the Upbeat programmer*/
	  /* writes something like:*/
	  /* Foo()()();*/
	  public boolean alreadyPostFixed;

	  public upbeatVal() { }
	  
	  public upbeatVal( ToBy t ) { toOrBy = t; }
	  
	  public upbeatVal( ChangeParam p ) { changeParam = p; }

	  public upbeatVal(int val) { ival=val; }

	  public upbeatVal(double val) { dval=val; }
	  
	  public upbeatVal(boolean val) { bval=val; }

	  public upbeatVal(String val) { code=val; }

	  public upbeatVal(Object val) { obj=val; }
	  
	  public upbeatVal(Type val) { type =val; }
	  
	  public upbeatVal(upbeatVal val) {
		  code = val.code;
		  numMusicians = val.numMusicians;
		  type = val.type;
		  toOrBy = val.toOrBy;
		  changeParam = val.changeParam;
		  ival = val.ival;
		  dval = val.dval;
		  sval = val.sval;
		  obj = val.obj;
	  }
	  
	  public upbeatVal clone() {
		  return new upbeatVal(this);
	  }
  }
  
  class FunctionType {
	  private LinkedList< upbeatVal.Type > mArgTypes;
	  private upbeatVal.Type mReturnType;
	  
	  public FunctionType() {
		  mArgTypes = new LinkedList< upbeatVal.Type >();
		  mReturnType = null;
	  }
	  
	  public void SetReturnType( upbeatVal.Type t ) {
		  mReturnType = t;
	  }
	  
	  public void SetArgs( LinkedList< upbeatVal.Type > args ) {
		  mArgTypes = args;
	  }
	  
	  public void AddArg( upbeatVal.Type arg ) {
		  mArgTypes.add( arg );
	  }
	  
	  public upbeatVal.Type GetReturnType() {
		  return mReturnType;
	  }
	  
	  public LinkedList< upbeatVal.Type > GetArgs() {
		  return mArgTypes;
	  }
	  
	  public boolean CheckArgTypes( LinkedList< upbeatVal.Type > args ){
		  Iterator< upbeatVal.Type > argIter = args.iterator();
		  Iterator< upbeatVal.Type > mArgIter = mArgTypes.iterator();
		  
		  /* If either of the types don't match up, return false*/
		  while( argIter.hasNext() && mArgIter.hasNext() ) {
		      if( argIter.next() != mArgIter.next() )
		    	  return false;
		  }
		      
		  /* If the number of arguments doesn't match up, return false*/
		  if( argIter.hasNext() || mArgIter.hasNext() )
			  return false;
		  
		  return true;
	  }
  }
  
  /* Pretty simple symbol table.  Can be expanded if need be*/
  class SymbolTable {
	  private Hashtable< String, upbeatVal.Type > mSymbols;
	  private Hashtable< String, Integer > mDefLine;
	  
	  private Hashtable< String, FunctionType > mFuncSymbols;
	  private Hashtable< String, Integer > mFuncDefLine;
	  
	  public SymbolTable parent;
	  
	  public boolean inConductorFunc;
	  public boolean inCueResponse;
	  
	  /* This is the name of the function we are in, if it exists...*/
	  public String myName;
	  public boolean returns;
	  
	  SymbolTable() {
		  /* special top-level symbol table*/
		  parent = null;
		  inConductorFunc = false;
		  inCueResponse = false;
		  myName = null;
		  mSymbols = new Hashtable<String, upbeatVal.Type>();
		  mDefLine = new Hashtable<String, Integer>();
		  mFuncSymbols = new Hashtable< String, FunctionType >();
		  mFuncDefLine = new Hashtable< String, Integer >();
	  }
	  SymbolTable(SymbolTable p) {
		  parent = p;
		  inConductorFunc = p.inConductorFunc;
		  inCueResponse = p.inCueResponse;
		  myName = p.myName;
		  mSymbols = new Hashtable<String, upbeatVal.Type>();
		  mDefLine = new Hashtable<String, Integer>();
		  mFuncSymbols = new Hashtable< String, FunctionType >();
		  mFuncDefLine = new Hashtable< String, Integer >();
	  }
	  
	  public void Returns() {
		  SymbolTable i = this;
		  
		  while( i.inConductorFunc && i.myName != null && i != null) {
			  i.returns = true;
			  i = i.parent;
		  }
		  
		  if( i.inConductorFunc || i.myName != null || i == null ) {
			  throw new Error( "Cannot figure out which function we 
are returning from" );
		  }
	  }
	  
	  public upbeatVal.Type GetCurrentReturnType() {
		  return GetFuncReturnType( myName );
	  }
	  
	  public void AddSymbol( String name, upbeatVal.Type type, int line ) {
		  mSymbols.put( name, type );
		  mDefLine.put( name, line );
	  }
	  
	  public void AddFuncSymbol( String name, FunctionType type, int line ) 
{
		  mFuncSymbols.put( name, type );
		  mFuncDefLine.put( name, line );
	  }
	  
	  public int numSymbols() {
		  if(parent != null) {
			  return mSymbols.size() + parent.numSymbols();
		  }
		  return mSymbols.size();
	  }
	  
	  public int numFuncSymbols() {
		  if(parent != null) {
			  return mFuncSymbols.size() + parent.numFuncSymbols();
		  }
		  return mFuncSymbols.size();
	  }
	  
	  /* returns null if the name does not exist!*/
	  public upbeatVal.Type GetType( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return null;
		  }
		  return i.mSymbols.get( name );
	  }
	  
	  /* returns null if the name does not exist!*/
	  public upbeatVal.Type GetFuncReturnType( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return null;
		  }
		  return i.mFuncSymbols.get( name ).GetReturnType();
	  }
	  
	  public boolean CheckFuncArgTypes( String name,  LinkedList< upbeatVal.
Type > argTypes ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return false;
		  }
		  return i.mFuncSymbols.get( name ).CheckArgTypes( argTypes );
	  }
	  
	  public LinkedList< upbeatVal.Type > GetParamTypes( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncSymbols.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return null;
		  }
		  return i.mFuncSymbols.get( name ).GetArgs();
	  }
	  
	  public int GetDefLine( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mDefLine.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return -1;
		  }
		  return i.mDefLine.get( name ); 
	  }
	  
	  public int GetFuncDefLine( String name ) {
		  SymbolTable i = this;
		  while (i != null && i.mFuncDefLine.get(name) == null) {
			  i = i.parent;
		  }
		  if (i==null) {
			  /* no symbol by that name.*/
			  return -1;
		  }
		  return i.mFuncDefLine.get( name ); 
	  }
	  
	  public String toString() {
		  String blah = new String();
		  Enumeration<String> keys = mSymbols.keys();
		  while(keys != null && keys.hasMoreElements()) {
			  String k = keys.nextElement();
			  blah = blah + "Var: " + k + " Type: " + mSymbols.get(k
) + "\n";
		  }
		  return blah;
	  }
  }
//#line 326 "parser.java"




public class parser
{

boolean yydebug;        //do I want debug output?
int yynerrs;            //number of errors so far
int yyerrflag;          //was there an error?
int yychar;             //the current working character

//########## MESSAGES ##########
//###############################################################
// method: debug
//###############################################################
void debug(String msg)
{
  if (yydebug)
    System.out.println(msg);
}

//########## STATE STACK ##########
final static int YYSTACKSIZE = 500;  //maximum stack size
int statestk[] = new int[YYSTACKSIZE]; //state stack
int stateptr;
int stateptrmax;                     //highest index of stackptr
int statemax;                        //state when highest index reached
//###############################################################
// methods: state stack push,pop,drop,peek
//###############################################################
final void state_push(int state)
{
  try {
		stateptr++;
		statestk[stateptr]=state;
	 }
	 catch (ArrayIndexOutOfBoundsException e) {
     int oldsize = statestk.length;
     int newsize = oldsize * 2;
     int[] newstack = new int[newsize];
     System.arraycopy(statestk,0,newstack,0,oldsize);
     statestk = newstack;
     statestk[stateptr]=state;
  }
}
final int state_pop()
{
  return statestk[stateptr--];
}
final void state_drop(int cnt)
{
  stateptr -= cnt; 
}
final int state_peek(int relative)
{
  return statestk[stateptr-relative];
}
//###############################################################
// method: init_stacks : allocate and prepare stacks
//###############################################################
final boolean init_stacks()
{
  stateptr = -1;
  val_init();
  return true;
}
//###############################################################
// method: dump_stacks : show n levels of the stacks
//###############################################################
void dump_stacks(int count)
{
int i;
  System.out.println("=index==state====value=     s:"+stateptr+"  v:"+valptr);
  for (i=0;i<count;i++)
    System.out.println(" "+i+"    "+statestk[i]+"      "+valstk[i]);
  System.out.println("======================");
}


//########## SEMANTIC VALUES ##########
//## **user defined:upbeatVal
String   yytext;//user variable to return contextual strings
upbeatVal yyval; //used to return semantic vals from action routines
upbeatVal yylval;//the 'lval' (result) I got from yylex()
upbeatVal valstk[] = new upbeatVal[YYSTACKSIZE];
int valptr;
//###############################################################
// methods: value stack push,pop,drop,peek.
//###############################################################
final void val_init()
{
  yyval=new upbeatVal();
  yylval=new upbeatVal();
  valptr=-1;
}
final void val_push(upbeatVal val)
{
  try {
    valptr++;
    valstk[valptr]=val;
  }
  catch (ArrayIndexOutOfBoundsException e) {
    int oldsize = valstk.length;
    int newsize = oldsize*2;
    upbeatVal[] newstack = new upbeatVal[newsize];
    System.arraycopy(valstk,0,newstack,0,oldsize);
    valstk = newstack;
    valstk[valptr]=val;
  }
}
final upbeatVal val_pop()
{
  return valstk[valptr--];
}
final void val_drop(int cnt)
{
  valptr -= cnt;
}
final upbeatVal val_peek(int relative)
{
  return valstk[valptr-relative];
}
final upbeatVal dup_yyval(upbeatVal val)
{
  return val;
}
//#### end semantic value section ####
public final static short IDENTIFIER=257;
public final static short CONSTANT=258;
public final static short STRING_LITERAL=259;
public final static short EQ_ASS=260;
public final static short LE_OP=261;
public final static short GE_OP=262;
public final static short EQ_OP=263;
public final static short NE_OP=264;
public final static short LESS_OP=265;
public final static short GREAT_OP=266;
public final static short AND_OP=267;
public final static short OR_OP=268;
public final static short INT=269;
public final static short FLOAT=270;
public final static short BOOL=271;
public final static short CUE=272;
public final static short PHRASE=273;
public final static short TIME=274;
public final static short INPUT=275;
public final static short CURR_CUE=276;
public final static short CURRENT_VALUE=277;
public final static short DATA=278;
public final static short MORE=279;
public final static short VALUE_AT=280;
public final static short CASE=281;
public final static short RETURN=282;
public final static short REPEAT=283;
public final static short TIME_SIGNATURE=284;
public final static short TEMPO=285;
public final static short ADD=286;
public final static short CONDUCTOR=287;
public final static short MUSICIAN=288;
public final static short IN=289;
public final static short CHANGE=290;
public final static short VOLUME=291;
public final static short INSTRUMENT=292;
public final static short PITCH=293;
public final static short TO=294;
public final static short BY=295;
public final static short DB=296;
public final static short RRPT=297;
public final static short YYERRCODE=256;
final static short yylhs[] = {                           -1,
    0,    1,    1,    4,    5,    7,    2,    6,    6,    6,
    6,   11,   11,   12,   11,    9,    9,   13,   13,   13,
   13,   13,   17,   17,   17,   20,   20,   14,   14,   18,
   22,   22,   23,   24,   19,   21,   21,   27,   25,   25,
   28,   28,   29,   29,   29,   30,   30,   30,   30,   30,
   31,   31,   33,   33,   33,   33,   32,   32,   32,   34,
   34,   34,   34,   35,   35,   35,   26,   26,   26,   26,
   26,   39,   39,   39,   38,   38,   38,   38,   38,   36,
   36,   36,   40,   40,   41,   41,   10,   10,   42,   43,
   43,   37,   37,   37,   37,   37,   37,    8,    8,   45,
   44,   46,   47,   44,   48,   44,   49,   50,   44,   15,
   16,   16,   52,   53,   53,   53,   54,   54,   51,   55,
   55,   57,   57,   58,   56,   56,   56,   59,   59,   59,
   59,   60,   60,   61,    3,    3,   64,   62,   63,   63,
   63,   65,   65,   67,   66,
};
final static short yylen[] = {                            2,
    3,    2,    2,    5,    3,    0,    5,    1,    2,    2,
    3,    2,    3,    0,    5,    1,    2,    1,    1,    1,
    1,    1,    1,    1,    1,    2,    3,    2,    1,    4,
    1,    2,    4,    0,    6,    1,    3,    1,    1,    3,
    1,    3,    1,    3,    3,    1,    3,    3,    3,    3,
    1,    3,    5,    5,    5,    5,    1,    3,    3,    1,
    3,    3,    3,    1,    2,    4,    1,    1,    3,    4,
    3,    6,    3,    3,    1,    1,    1,    1,    3,    1,
    1,    1,    1,    3,    1,    3,    2,    3,    2,    1,
    3,    1,    1,    1,    1,    1,    1,    1,    2,    0,
    5,    0,    0,    7,    0,    6,    0,    0,    8,    4,
    2,    2,    4,    1,    1,    1,    1,    1,    2,    1,
    1,    4,    5,    3,    2,    2,    0,    1,    3,    1,
    3,    3,    4,    2,    1,    2,    0,    6,    2,    2,
    3,    1,    2,    0,    3,
};
final static short yydefred[] = {                         0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    2,    3,    0,    5,    6,    0,    0,  135,    0,    0,
    0,  136,    4,    0,   77,   78,   80,   81,   92,   93,
   94,   95,   96,   97,    0,   76,    0,    0,    0,    0,
    0,    0,   29,    0,    0,   82,    0,    0,    0,    0,
   18,   16,   19,   20,   21,   22,   23,   24,   25,    0,
    0,    0,    0,    0,    0,   46,    0,    0,   60,    0,
    0,   67,   68,    0,   98,    0,    0,    0,  120,  121,
  137,    0,    0,    0,   75,   26,    0,    0,    0,  114,
  115,  116,    0,    0,    0,    0,    0,   12,    0,    0,
    0,    0,    7,    0,    0,   99,    0,   17,    0,    0,
    0,   28,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
   65,    0,   89,   87,  111,  112,    0,  119,    0,    0,
    0,    0,  100,    0,   73,   74,    0,    0,    0,    0,
   27,    0,    0,  117,  118,    0,    0,    0,    0,  124,
   13,    0,    0,   79,    0,    0,    0,   88,    0,   37,
   69,   83,    0,   71,    0,    0,    0,   49,   50,   47,
   48,    0,    0,    0,    0,   52,   61,   62,   63,    0,
    0,    0,  134,  125,  126,    0,    0,    0,    0,    0,
   85,    0,    0,   30,   32,   34,  110,  113,  129,  131,
    0,    0,    0,   66,   70,    0,    0,    0,   91,  105,
    0,    0,    0,  139,    0,    0,  140,  138,  101,  103,
    0,    0,    0,    0,    0,  123,   15,   84,    0,    0,
    0,    0,  133,    0,  144,  143,  141,    0,   86,   72,
   33,   35,    0,    0,  106,  108,  145,  104,   53,   55,
   54,   56,    0,  109,
};
final static short yydgoto[] = {                          3,
    4,   10,   17,    5,    6,   47,   20,   48,   49,   50,
   51,  100,   52,   53,   54,   55,   56,   57,   58,   59,
   60,  149,  150,  234,   61,   62,  236,   63,   64,   65,
   66,   67,  186,   68,   69,   70,  163,   72,   73,  173,
  200,   74,  133,   75,  199,  144,  248,  241,  221,  263,
   76,   77,   93,  156,   78,  138,   79,   80,  139,  140,
  141,   18,  198,  142,  224,  225,  244,
};
final static short yysindex[] = {                      -236,
 -239, -227,    0, -232, -228, -225,   17,    7,  -52, -220,
    0,    0, -182,    0,    0, -176, -220,    0,   26,  -33,
  -32,    0,    0,   49,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,   60,    0,  -15,  885,   75,    1,
 -145,  -53,    0,   62,  366,    0,   -8, -129,  -33,  -33,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   70,
 -149,  -31, -136, -141, -162,    0,  -37,   -4,    0,    1,
 -123,    0,    0,   95,    0,  102,  107,  -38,    0,    0,
    0,  127, -153,  132,    0,    0,  111,    1,    1,    0,
    0,    0, -142,   58,   85,  -94, -112,    0,   92,  -78,
  145,  169,    0,   49,  -45,    0, -129,    0, -129,  -33,
  155,    0,    1,    1,  894,  -62,    1,    1,    1,    1,
    1,    1,    1,    1,    1,  -29,    1,    1,    1,   -1,
    0,  -39,    0,    0,    0,    0,  -94,    0,  -74,  -38,
  -38,   -3,    0,  -78,    0,    0,  178,    1,   98,  132,
    0,  187,  173,    0,    0,    1,  -94,  -94,  -63,    0,
    0,   -3,  -13,    0,    1,  193, -129,    0, -136,    0,
    0,    0,   43,    0, -141, -162, -162,    0,    0,    0,
    0,   -4,   -4,    1,    1,    0,    0,    0,    0,    1,
  194,  -51,    0,    0,    0,  168,   27,  126,  138,   57,
    0,    1,  223,    0,    0,    0,    0,    0,    0,    0,
    1,  122,    5,    0,    0,    1,  218,  230,    0,    0,
  -78,    1,    0,    0,   16,  168,    0,    0,    0,    0,
  -78,  240,  271,  271, -149,    0,    0,    0,    1,    1,
  138,   69,    0,  138,    0,    0,    0,  138,    0,    0,
    0,    0,  -24,  -12,    0,    0,    0,    0,    0,    0,
    0,    0,  138,    0,
};
final static short yyrindex[] = {                         0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,  282,    0,    0,    0,
    0,    0,    0,  463,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,   55,    0,    0,    0,  163,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  870,  424,  843,  803,  574,    0,  554,  444,    0,    0,
    0,    0,    0,    0,    0,    0,    0,  231,    0,    0,
    0,  221,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0, -122, -119,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,  164,    0,  167,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,  387,
    0,  235,    0,    0,    0,    0,    0,    0,    0,  231,
  231,    0,    0,    0,    0,    0,    0,    0,    0,  170,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,  180,    0,  864,    0,
    0,    0,    0,    0,  823,  741,  765,    0,    0,    0,
    0,  480,  500,    0,    0,    0,    0,    0,    0,    0,
  330,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  121,    0,   38,    0,    0,    0,    0,    0,    0,    0,
    0,  130,  317,    0,  181,    0,    0,    0,    0,    0,
    0,    0,    0,    0,  -55,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,
};
final static short yygindex[] = {                         0,
    0,    0,    0,  301,  307,    0,    0,  -22,  -26,  -64,
 -183,    0,  -36,    0,    0,    0,    0,    0,    0,    0,
  999,  165,    0,    0, -190,  847,   96,  209,  214,   81,
   36,    0,    0,   82,  -35,    0,    2,    0,    0,    0,
  112,  -48,    0,  -34,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,   90,    0,    0,  -19,    0,
    0,  315,    0,    0, -172,    0,    0,
};
final static int YYTABLESIZE=1239;
static short yytable[];
static { yytable();}
static void yytable(){
yytable = new short[]{                         46,
  191,  111,   38,   38,   96,  124,   45,  125,  115,   27,
  184,   28,  108,  106,  116,  229,  259,   99,    7,  137,
  235,   71,   97,  110,  227,   43,  107,  109,  261,   46,
    8,  235,  129,   46,  131,  162,   45,  127,  115,   27,
   45,   28,  128,   27,  116,   28,  102,    1,    2,  105,
  105,   71,  246,  247,    9,   43,    2,  255,    1,   46,
  257,  185,  108,   13,  258,   14,   45,   16,  260,   27,
   15,   28,  106,  108,  106,   19,  159,  197,   90,  264,
  262,   90,   21,  215,   23,   43,  216,  167,   82,   44,
   81,  187,  188,  189,   46,  201,   90,  230,  120,  121,
  231,   45,  122,  123,   27,   83,   28,   84,  105,  256,
  105,  105,  231,  111,   88,  196,  103,  192,  113,   44,
   43,  118,  119,  145,   46,  146,  147,  104,  112,  214,
  117,   45,  106,  132,   27,  212,   28,  209,  210,   29,
   30,   31,   32,   33,   34,   90,   91,   92,  111,   44,
   43,  154,  155,  134,   46,  178,  179,  180,  181,  108,
  135,   45,   94,   95,   27,  136,   28,  143,  105,  151,
  226,  148,  201,  128,  128,  108,  130,  130,  122,  122,
   43,  157,  249,  160,   44,  164,   98,  132,  132,  108,
   29,   30,   31,   32,   33,   34,  251,  252,  176,  177,
   46,   38,   38,   94,   95,  182,  183,   45,  158,  165,
   27,  166,   28,  168,   44,  174,  161,  202,   94,   95,
  190,  193,  204,   24,   25,   26,   43,  206,  114,  194,
  195,  207,  191,  211,  220,   29,   30,   31,   32,   33,
   34,   35,   36,  213,   44,  222,  237,   37,   38,   39,
  228,  126,   40,   85,   25,   26,   41,   85,   25,   26,
   44,  239,   42,  233,  190,   29,   30,   31,   32,   33,
   34,   35,   36,  240,  245,   35,   36,   37,   38,   39,
  250,    1,   40,   85,   25,  223,   41,    8,    9,  127,
   44,   10,   42,   90,   31,   29,   30,   31,   32,   33,
   34,   35,   36,   46,   11,  142,   12,   37,   38,   39,
   45,   11,   40,   27,  205,   28,   41,  243,   85,   25,
   26,  169,   42,   14,   14,   14,   14,   14,   14,   43,
  175,   22,  242,    0,    0,    0,   35,   36,    0,    0,
    0,    0,   37,   38,   39,    0,    0,   40,   85,   25,
   26,   41,    0,   78,    0,    0,   78,   42,   78,   78,
    0,   78,   78,   78,    0,    0,   35,   36,    0,    0,
    0,    0,   37,   38,   39,   78,    0,   40,   85,   25,
   26,   41,    0,    0,    0,    0,    0,   42,    0,    0,
    0,    0,    0,   44,    0,    0,   35,   36,   46,    0,
    0,    0,   37,   38,   39,   45,    0,   40,   27,    0,
   28,   41,    0,    0,    0,    0,    0,   42,    0,   64,
    0,    0,    0,   64,   85,   25,  223,   64,   64,   64,
   64,   64,    0,   64,    0,    0,    0,    0,    0,  144,
    0,    0,   35,   36,   64,   64,    0,    0,   37,   38,
   39,    0,    0,   40,    0,    0,   64,   41,    0,    0,
   64,    0,    0,   42,   64,   64,   64,   64,   64,    0,
   64,    0,    0,    0,    0,    0,   57,    0,    0,   64,
    0,    0,   64,   57,   57,    0,   57,   57,   57,  102,
  102,  102,  102,  102,  102,    0,    0,    0,    0,   75,
    0,   57,   57,    0,   75,   75,    0,   75,   75,   75,
    0,    0,   58,    0,    0,    0,   64,    0,    0,   58,
   58,   75,   58,   58,   58,    0,    0,   85,   25,   26,
    0,    0,   59,    0,    0,    0,   57,   58,   58,   59,
   59,    0,   59,   59,   59,   35,   36,    0,    0,    0,
    0,   37,   38,   39,    0,    0,   40,   59,   59,    0,
   41,    0,    0,    0,    0,    0,   42,    0,    0,    0,
    0,    0,   58,    0,    0,    0,   78,   78,   78,   78,
   78,   78,   78,   78,   78,    0,   51,    0,    0,    0,
    0,    0,   59,   51,   51,    0,    0,   51,  107,  107,
  107,  107,  107,  107,    0,   78,   43,    0,    0,    0,
    0,   51,   51,   43,   43,    0,   43,   43,   43,    0,
    0,    0,   85,   25,   26,    0,    0,    0,    0,    0,
    0,   43,   43,    0,   29,   30,   31,   32,   33,   34,
   35,   36,    0,   64,   64,   64,   51,   64,   64,   64,
   64,   64,   64,   64,   64,    0,    0,    0,    0,    0,
    0,   64,   64,    0,    0,    0,   43,    0,    0,    0,
    0,    0,    0,    0,    0,   64,    0,    0,    0,    0,
   64,   64,   64,    0,   64,   64,   64,   64,   64,   64,
   64,   64,    0,    0,    0,    0,    0,    0,   64,   64,
   57,   57,   57,    0,   57,   57,   57,   57,   57,   57,
   57,   57,   64,    0,    0,    0,    0,    0,   57,   57,
    0,    0,   75,   75,   75,   75,   75,   75,   75,   75,
   75,    0,   57,    0,    0,    0,   58,   58,   58,    0,
   58,   58,   58,   58,   58,   58,   58,   58,    0,    0,
    0,   75,    0,    0,   58,   58,   59,   59,   59,    0,
   59,   59,   59,   59,   59,   59,   59,   59,   58,    0,
    0,    0,    0,   44,   59,   59,    0,    0,    0,    0,
   44,   44,    0,   44,   44,   44,    0,    0,   59,    0,
    0,    0,    0,    0,    0,    0,    0,   45,   44,   44,
    0,    0,    0,    0,   45,   45,    0,   45,   45,   45,
   51,   51,   51,    0,   51,   51,   51,   51,   51,   51,
   51,   51,   45,   45,    0,    0,    0,    0,   51,   51,
   43,   43,   43,   44,    0,   41,   43,   43,    0,    0,
   43,   43,   41,   41,    0,   41,   41,   41,   43,   43,
    0,    0,    0,    0,    0,   42,    0,   45,    0,    0,
   41,   41,   42,   42,    0,   42,   42,   42,    0,    0,
    0,    0,    0,    0,    0,   39,    0,    0,    0,    0,
   42,   42,   39,   39,    0,   39,   39,   39,    0,    0,
    0,    0,    0,    0,    0,   41,   40,    0,    0,    0,
   39,   39,   36,   40,   40,    0,   40,   40,   40,   36,
   36,    0,   36,   36,   36,   42,  130,   46,    0,    0,
    0,   40,   40,    0,   45,    0,   46,   27,   36,   28,
    0,    0,    0,   45,  171,   39,   27,    0,   28,    0,
    0,    0,    0,   86,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,   40,    0,    0,  130,
    0,    0,   36,  130,  130,  130,  130,  130,  130,  130,
  130,  130,    0,  130,  130,  130,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,   44,   44,   44,
    0,    0,    0,   44,   44,    0,    0,   44,   44,    0,
    0,  130,    0,    0,    0,   44,   44,    0,    0,    0,
    0,   45,   45,   45,    0,    0,    0,   45,   45,    0,
    0,   45,   45,    0,    0,    0,   87,    0,   89,   45,
   45,    0,    0,  101,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,  130,    0,   41,
   41,   41,    0,    0,    0,    0,    0,    0,  130,   41,
   41,    0,    0,    0,    0,    0,    0,   41,   41,   42,
   42,   42,    0,    0,    0,    0,  152,  153,    0,   42,
   42,    0,    0,    0,    0,    0,    0,   42,   42,   39,
   39,   39,    0,    0,    0,    0,    0,    0,    0,    0,
   39,    0,  170,  172,    0,    0,    0,   39,   39,    0,
   40,   40,   40,    0,    0,    0,   36,   36,   36,    0,
    0,   40,    0,    0,    0,    0,    0,    0,   40,   40,
    0,   85,   25,   26,   36,   36,  203,    0,    0,    0,
   85,   25,   26,    0,  208,    0,    0,    0,    0,   35,
   36,    0,    0,    0,    0,    0,    0,    0,   35,   36,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,  217,  218,    0,    0,    0,    0,  219,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  232,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,  238,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,  253,  254,
};
}
static short yycheck[];
static { yycheck(); }
static void yycheck() {
yycheck = new short[] {                         33,
   40,   50,   58,   59,   58,   43,   40,   45,   40,   43,
   40,   45,   49,   48,   46,  199,   41,   44,  258,   58,
  211,   20,   42,   50,  197,   59,   49,   50,   41,   33,
  258,  222,   37,   33,   70,  100,   40,   42,   40,   43,
   40,   45,   47,   43,   46,   45,   45,  284,  285,   48,
   49,   50,  225,  226,  287,   59,  285,  241,  284,   33,
  244,   91,   99,   47,  248,   59,   40,  288,   93,   43,
  123,   45,  107,  110,  109,  258,   96,  142,   41,  263,
   93,   44,  259,   41,   59,   59,   44,  110,   40,  123,
  123,  127,  128,  129,   33,  144,   59,   41,  261,  262,
   44,   40,  265,  266,   43,   46,   45,  123,  107,   41,
  109,  110,   44,  162,   40,  142,  125,  137,  268,  123,
   59,  263,  264,  277,   33,  279,  280,  257,   59,  165,
  267,   40,  167,  257,   43,  162,   45,  157,  158,  269,
  270,  271,  272,  273,  274,  291,  292,  293,  197,  123,
   59,  294,  295,   59,   33,  120,  121,  122,  123,  196,
   59,   40,  257,  258,   43,   59,   45,   41,  167,   59,
  197,   40,  221,  296,  297,  212,  296,  297,   58,   59,
   59,  124,  231,  296,  123,   41,  125,   58,   59,  226,
  269,  270,  271,  272,  273,  274,  233,  234,  118,  119,
   33,  257,  258,  257,  258,  124,  125,   40,  124,   41,
   43,  257,   45,   59,  123,  278,  125,   40,  257,  258,
  260,  296,  125,  257,  258,  259,   59,   41,  260,  140,
  141,   59,   40,  297,   41,  269,  270,  271,  272,  273,
  274,  275,  276,  257,  123,  297,  125,  281,  282,  283,
  125,  289,  286,  257,  258,  259,  290,  257,  258,  259,
  123,   44,  296,   41,  260,  269,  270,  271,  272,  273,
  274,  275,  276,   44,  259,  275,  276,  281,  282,  283,
   41,    0,  286,  257,  258,  259,  290,  125,  125,   59,
  123,  125,  296,   59,  125,  269,  270,  271,  272,  273,
  274,  275,  276,   33,  125,  125,    6,  281,  282,  283,
   40,    5,  286,   43,  150,   45,  290,  222,  257,  258,
  259,  113,  296,  269,  270,  271,  272,  273,  274,   59,
  117,   17,  221,   -1,   -1,   -1,  275,  276,   -1,   -1,
   -1,   -1,  281,  282,  283,   -1,   -1,  286,  257,  258,
  259,  290,   -1,   37,   -1,   -1,   40,  296,   42,   43,
   -1,   45,   46,   47,   -1,   -1,  275,  276,   -1,   -1,
   -1,   -1,  281,  282,  283,   59,   -1,  286,  257,  258,
  259,  290,   -1,   -1,   -1,   -1,   -1,  296,   -1,   -1,
   -1,   -1,   -1,  123,   -1,   -1,  275,  276,   33,   -1,
   -1,   -1,  281,  282,  283,   40,   -1,  286,   43,   -1,
   45,  290,   -1,   -1,   -1,   -1,   -1,  296,   -1,   33,
   -1,   -1,   -1,   37,  257,  258,  259,   41,   42,   43,
   44,   45,   -1,   47,   -1,   -1,   -1,   -1,   -1,  123,
   -1,   -1,  275,  276,   58,   59,   -1,   -1,  281,  282,
  283,   -1,   -1,  286,   -1,   -1,   33,  290,   -1,   -1,
   37,   -1,   -1,  296,   41,   42,   43,   44,   45,   -1,
   47,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,   93,
   -1,   -1,   59,   40,   41,   -1,   43,   44,   45,  269,
  270,  271,  272,  273,  274,   -1,   -1,   -1,   -1,   37,
   -1,   58,   59,   -1,   42,   43,   -1,   45,   46,   47,
   -1,   -1,   33,   -1,   -1,   -1,   93,   -1,   -1,   40,
   41,   59,   43,   44,   45,   -1,   -1,  257,  258,  259,
   -1,   -1,   33,   -1,   -1,   -1,   93,   58,   59,   40,
   41,   -1,   43,   44,   45,  275,  276,   -1,   -1,   -1,
   -1,  281,  282,  283,   -1,   -1,  286,   58,   59,   -1,
  290,   -1,   -1,   -1,   -1,   -1,  296,   -1,   -1,   -1,
   -1,   -1,   93,   -1,   -1,   -1,  260,  261,  262,  263,
  264,  265,  266,  267,  268,   -1,   33,   -1,   -1,   -1,
   -1,   -1,   93,   40,   41,   -1,   -1,   44,  269,  270,
  271,  272,  273,  274,   -1,  289,   33,   -1,   -1,   -1,
   -1,   58,   59,   40,   41,   -1,   43,   44,   45,   -1,
   -1,   -1,  257,  258,  259,   -1,   -1,   -1,   -1,   -1,
   -1,   58,   59,   -1,  269,  270,  271,  272,  273,  274,
  275,  276,   -1,  257,  258,  259,   93,  261,  262,  263,
  264,  265,  266,  267,  268,   -1,   -1,   -1,   -1,   -1,
   -1,  275,  276,   -1,   -1,   -1,   93,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,  289,   -1,   -1,   -1,   -1,
  257,  258,  259,   -1,  261,  262,  263,  264,  265,  266,
  267,  268,   -1,   -1,   -1,   -1,   -1,   -1,  275,  276,
  257,  258,  259,   -1,  261,  262,  263,  264,  265,  266,
  267,  268,  289,   -1,   -1,   -1,   -1,   -1,  275,  276,
   -1,   -1,  260,  261,  262,  263,  264,  265,  266,  267,
  268,   -1,  289,   -1,   -1,   -1,  257,  258,  259,   -1,
  261,  262,  263,  264,  265,  266,  267,  268,   -1,   -1,
   -1,  289,   -1,   -1,  275,  276,  257,  258,  259,   -1,
  261,  262,  263,  264,  265,  266,  267,  268,  289,   -1,
   -1,   -1,   -1,   33,  275,  276,   -1,   -1,   -1,   -1,
   40,   41,   -1,   43,   44,   45,   -1,   -1,  289,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,   58,   59,
   -1,   -1,   -1,   -1,   40,   41,   -1,   43,   44,   45,
  257,  258,  259,   -1,  261,  262,  263,  264,  265,  266,
  267,  268,   58,   59,   -1,   -1,   -1,   -1,  275,  276,
  257,  258,  259,   93,   -1,   33,  263,  264,   -1,   -1,
  267,  268,   40,   41,   -1,   43,   44,   45,  275,  276,
   -1,   -1,   -1,   -1,   -1,   33,   -1,   93,   -1,   -1,
   58,   59,   40,   41,   -1,   43,   44,   45,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,
   58,   59,   40,   41,   -1,   43,   44,   45,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   93,   33,   -1,   -1,   -1,
   58,   59,   33,   40,   41,   -1,   43,   44,   45,   40,
   41,   -1,   43,   44,   45,   93,   70,   33,   -1,   -1,
   -1,   58,   59,   -1,   40,   -1,   33,   43,   59,   45,
   -1,   -1,   -1,   40,   41,   93,   43,   -1,   45,   -1,
   -1,   -1,   -1,   59,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   93,   -1,   -1,  113,
   -1,   -1,   93,  117,  118,  119,  120,  121,  122,  123,
  124,  125,   -1,  127,  128,  129,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  257,  258,  259,
   -1,   -1,   -1,  263,  264,   -1,   -1,  267,  268,   -1,
   -1,  165,   -1,   -1,   -1,  275,  276,   -1,   -1,   -1,
   -1,  257,  258,  259,   -1,   -1,   -1,  263,  264,   -1,
   -1,  267,  268,   -1,   -1,   -1,   38,   -1,   40,  275,
  276,   -1,   -1,   45,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  211,   -1,  257,
  258,  259,   -1,   -1,   -1,   -1,   -1,   -1,  222,  267,
  268,   -1,   -1,   -1,   -1,   -1,   -1,  275,  276,  257,
  258,  259,   -1,   -1,   -1,   -1,   88,   89,   -1,  267,
  268,   -1,   -1,   -1,   -1,   -1,   -1,  275,  276,  257,
  258,  259,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  268,   -1,  114,  115,   -1,   -1,   -1,  275,  276,   -1,
  257,  258,  259,   -1,   -1,   -1,  257,  258,  259,   -1,
   -1,  268,   -1,   -1,   -1,   -1,   -1,   -1,  275,  276,
   -1,  257,  258,  259,  275,  276,  148,   -1,   -1,   -1,
  257,  258,  259,   -1,  156,   -1,   -1,   -1,   -1,  275,
  276,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  275,  276,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,  184,  185,   -1,   -1,   -1,   -1,  190,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  202,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,  216,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,  239,  240,
};
}
final static short YYFINAL=3;
final static short YYMAXTOKEN=297;
final static String yyname[] = {
"end-of-file",null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,"'!'",null,null,null,"'%'",null,null,"'('","')'","'*'","'+'",
"','","'-'","'.'","'/'",null,null,null,null,null,null,null,null,null,null,"':'",
"';'",null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,"'['",null,"']'",null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,"'{'","'|'","'}'",null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,"IDENTIFIER","CONSTANT",
"STRING_LITERAL","EQ_ASS","LE_OP","GE_OP","EQ_OP","NE_OP","LESS_OP","GREAT_OP",
"AND_OP","OR_OP","INT","FLOAT","BOOL","CUE","PHRASE","TIME","INPUT","CURR_CUE",
"CURRENT_VALUE","DATA","MORE","VALUE_AT","CASE","RETURN","REPEAT",
"TIME_SIGNATURE","TEMPO","ADD","CONDUCTOR","MUSICIAN","IN","CHANGE","VOLUME",
"INSTRUMENT","PITCH","TO","BY","DB","RRPT",
};
final static String yyrule[] = {
"$accept : upbeat_src",
"upbeat_src : header conductor_block musician_blocks",
"header : header_time_sig header_tempo",
"header : header_tempo header_time_sig",
"header_time_sig : TIME_SIGNATURE CONSTANT '/' CONSTANT ';'",
"header_tempo : TEMPO CONSTANT ';'",
"$$1 :",
"conductor_block : CONDUCTOR '{' $$1 conductor_body '}'",
"conductor_body : function_definition_list",
"conductor_body : statement_list function_definition_list",
"conductor_body : declaration_list function_definition_list",
"conductor_body : declaration_list statement_list function_definition_list",
"compound_statement : '{' '}'",
"compound_statement : '{' statement_list '}'",
"$$2 :",
"compound_statement : '{' $$2 declaration_list statement_list '}'",
"statement_list : statement",
"statement_list : statement_list statement",
"statement : compound_statement",
"statement : expression_statement",
"statement : adding_cue_statement",
"statement : musical_statement",
"statement : flow_control_statement",
"flow_control_statement : case_statement",
"flow_control_statement : repeat_statement",
"flow_control_statement : return_statement",
"return_statement : RETURN ';'",
"return_statement : RETURN expression ';'",
"expression_statement : expression ';'",
"expression_statement : ';'",
"case_statement : CASE '{' case_list '}'",
"case_list : case",
"case_list : case case_list",
"case : '(' expression ')' statement",
"$$3 :",
"repeat_statement : REPEAT '(' expression ')' $$3 statement",
"expression : logical_or_expression",
"expression : postfix_expression EQ_ASS expression",
"constant_expression : logical_or_expression",
"logical_or_expression : logical_and_expression",
"logical_or_expression : logical_or_expression OR_OP logical_and_expression",
"logical_and_expression : equality_expression",
"logical_and_expression : logical_and_expression AND_OP equality_expression",
"equality_expression : relational_expression",
"equality_expression : equality_expression EQ_OP relational_expression",
"equality_expression : equality_expression NE_OP relational_expression",
"relational_expression : range_expression",
"relational_expression : relational_expression LESS_OP range_expression",
"relational_expression : relational_expression GREAT_OP range_expression",
"relational_expression : relational_expression LE_OP range_expression",
"relational_expression : relational_expression GE_OP range_expression",
"range_expression : additive_expression",
"range_expression : additive_expression IN range_specifier",
"range_specifier : '(' expression ',' expression ')'",
"range_specifier : '[' expression ',' expression ')'",
"range_specifier : '(' expression ',' expression ']'",
"range_specifier : '[' expression ',' expression ']'",
"additive_expression : multiplication_expression",
"additive_expression : additive_expression '+' multiplication_expression",
"additive_expression : additive_expression '-' multiplication_expression",
"multiplication_expression : cast_expression",
"multiplication_expression : multiplication_expression '*' cast_expression",
"multiplication_expression : multiplication_expression '/' cast_expression",
"multiplication_expression : multiplication_expression '%' cast_expression",
"cast_expression : postfix_expression",
"cast_expression : unary_operator cast_expression",
"cast_expression : '(' type_specifier ')' cast_expression",
"postfix_expression : primary_expression",
"postfix_expression : input_expression",
"postfix_expression : postfix_expression '(' ')'",
"postfix_expression : postfix_expression '(' argument_expression_list ')'",
"postfix_expression : postfix_expression '.' DATA",
"input_expression : INPUT '.' VALUE_AT '(' expression ')'",
"input_expression : INPUT '.' CURRENT_VALUE",
"input_expression : INPUT '.' MORE",
"primary_expression : IDENTIFIER",
"primary_expression : CURR_CUE",
"primary_expression : CONSTANT",
"primary_expression : STRING_LITERAL",
"primary_expression : '(' expression ')'",
"unary_operator : '+'",
"unary_operator : '-'",
"unary_operator : '!'",
"argument_expression_list : expression",
"argument_expression_list : argument_expression_list ',' expression",
"parameter_list : declaration",
"parameter_list : parameter_list ',' declaration",
"declaration_list : declaration ';'",
"declaration_list : declaration_list declaration ';'",
"declaration : type_specifier declarator",
"declarator : IDENTIFIER",
"declarator : IDENTIFIER EQ_ASS expression",
"type_specifier : INT",
"type_specifier : FLOAT",
"type_specifier : BOOL",
"type_specifier : CUE",
"type_specifier : PHRASE",
"type_specifier : TIME",
"function_definition_list : function_definition",
"function_definition_list : function_definition_list function_definition",
"$$4 :",
"function_definition : IDENTIFIER '(' ')' $$4 compound_statement",
"$$5 :",
"$$6 :",
"function_definition : IDENTIFIER '(' $$5 parameter_list ')' $$6 compound_statem
ent",
"$$7 :",
"function_definition : type_specifier IDENTIFIER '(' ')' $$7 compound_statement"
,
"$$8 :",
"$$9 :",
"function_definition : type_specifier IDENTIFIER '(' $$8 parameter_list ')' $$9 
compound_statement",
"adding_cue_statement : ADD expression expression ';'",
"musical_statement : phrase_expression ';'",
"musical_statement : phrase_control_expression ';'",
"phrase_control_expression : CHANGE change_parameter to_by_option expression",
"change_parameter : VOLUME",
"change_parameter : INSTRUMENT",
"change_parameter : PITCH",
"to_by_option : TO",
"to_by_option : BY",
"phrase_expression : first_phrase continuing_phrases",
"first_phrase : repeated_phrase",
"first_phrase : one_time_phrase",
"repeated_phrase : DB ':' musical_phrase RRPT",
"repeated_phrase : DB ':' musical_phrase RRPT constant_expression",
"one_time_phrase : DB musical_phrase DB",
"continuing_phrases : continued_repeated_phrase continuing_phrases",
"continuing_phrases : continued_one_time_phrase continuing_phrases",
"continuing_phrases :",
"musical_phrase : IDENTIFIER",
"musical_phrase : IDENTIFIER '|' musical_phrase",
"musical_phrase : CONSTANT",
"musical_phrase : CONSTANT '|' musical_phrase",
"continued_repeated_phrase : ':' musical_phrase RRPT",
"continued_repeated_phrase : ':' musical_phrase RRPT constant_expression",
"continued_one_time_phrase : musical_phrase DB",
"musician_blocks : musician_block",
"musician_blocks : musician_blocks musician_block",
"$$10 :",
"musician_block : MUSICIAN STRING_LITERAL '{' $$10 musician_body '}'",
"musician_body : statement_list cue_response_list",
"musician_body : declaration_list cue_response_list",
"musician_body : declaration_list statement_list cue_response_list",
"cue_response_list : cue_response",
"cue_response_list : cue_response cue_response_list",
"$$11 :",
"cue_response : STRING_LITERAL $$11 compound_statement",
};

//#line 1992 "upbeat-a.yacc"
  // *******************************************
  // JAVA CODE THAT IS ADDED TO THE PARSER CLASS
  // *******************************************
  /* a reference to the lexer object */
  private Yylex lexer;
  private SymbolTable current_symbol_table;
  public static int yyerrors;
  public static int yywarnings;
  // Total number of errors encountered
  
  private final Hashtable<String, short[][]> optable = new Hashtable<String, sho
rt[][]>();
  private final short castTable[][];
  
  // This is appended to the end of any temporary variable names we create
  // This ensures that all temporary variables have unique names.  Also, it
  // keeps track of how many there are (if we care)
  // DO NOT USE THIS DIRECTLY!  INSTEAD CALL TempIdentifier()!
  private int tempCounter;
  
  private int TempIdentifier() {
	  tempCounter++;
	  return tempCounter;
  }
  
  /* interface to the lexer */
  private int yylex () {
    int yyl_return = -1;
    try {
      yyl_return = lexer.yylex();
    }
    catch (IOException e) {
      System.err.println("IO error :"+e);
    }
    return yyl_return;
  }

  /* error reporting */
  public void yyerror (String error) {
    System.err.println ("Error: " + error + " at " + lexer.lexer_loc());
    yyerrors++;
  }
  
  /* warning reporting */
  public void yywarning (String warning) {
	  System.out.println("Warning: " + warning + " at " + lexer.lexer_loc())
;
	  yywarnings++;
  }

  /* lexer is created in the constructor */
  public parser(Reader r) {
    lexer = new Yylex(r, this);
    yyerrors = 0;
    yywarnings = 0;
    current_symbol_table = new SymbolTable();
    	// since we have no args, the parent is void, and it's a special top-lev
el (global) symboltable.
    
    // This is used to check to see if a cast is legal
    // Note that casting a string to a string is illegal
    // This is because we don't have an actual keyword for string types
    /*
     * 0. Not allowed.  Give an error
     * 1. Allowed, but give a warning
     * 2. Allowed, perform cast and don't give any message
     * 3. Allowed, and no cast needed
     */
    castTable = new short[][]{
    	/* from/to	  ubVOID, ubINT, ubFLOAT, ubBOOL, ubCUE, ubPHRASE,ubTIME
,ubSTRING */
    	/*ubVOID*/ 	{   3, 		0,		0,		0,	
	0,		0,		0,		0	},
        /*ubINT*/	{   0,		3,		2,		0,	
	0,		0,		2,		0	},
        /*ubFLOAT*/	{   0,		1,		3,		0,	
	0,		0,		1,		0	},
        /*ubBOOL*/	{   0,		0,		0,		3,	
	0,		0,		0,		0	},
        /*ubCUE*/	{   0,		0,		0,		0,	
	3,		0,		0,		0	},
        /*ubPHRASE*/{   0,		0,		0,		0,	
	0,		3,		0,		0	},
        /*ubTIME*/	{   0,		2,		1,		0,	
	0,		0,		3,		0	},
        /*ubSTRING*/{   0,		0,		0,		0,	
	0,		0,		0,		0	}
    };
  
    /*
     * 0. Not allowed
     * 1. Allowed; use both arguments as-is; result type is the same.
     * 2. Allowed; use both arguments as-is; result is java bool
     * 3. Special: assigning strings (rval) to CUE types (lval)
     * 4. Special: assigning strings (rval) to PHRASE types (lval)
     * 5. Special: cast right argument from java int to java String; result is l
eft type
     * 6. Special: cast left argument from java int to java String; result is ri
ght type
     * 7. Allowed: cast right argument to left type; result is left type
     * 8. Allowed: cast left argument to right type; result is right type
     * 9. Allowed: cast right argument to left type; result is bool
     * 10. Allowed: cast left argument to right type; result is bool
     */
    optable.put(new String("="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		7,		
0,		0,		0,		7,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		7,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		1,		0,		0,		3	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		1,		0,		4	},
    	/*ubTIME*/	{	0,		7,		7,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("+"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		6	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		5,		0,		0,	
	0,		0,		0,		1	}
      });
    optable.put(new String("-"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("*"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("/"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		8,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		7,		1,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("%"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		1,		0,		
0,		0,		0,		8,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		7,		0,		
0,		0,		0,		1,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("<"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String(">"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("<="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String(">="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		10,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		9,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("=="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		0,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		0,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
2,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		2,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		2,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("!="), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		2,		0,		
0,		0,		0,		9,		0	},
    	/*ubFLOAT*/	{	0,		0,		2,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
2,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		2,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		2,		0,		0	},
    	/*ubTIME*/	{	0,		10,		0,		
0,		0,		0,		2,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("&&"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });
    optable.put(new String("||"), new short[][]{
    	/* left/right	ubVOID,	ubINT,	ubFLOAT,ubBOOL,	ubCUE,	ubPHRASE,ubTIME,
ubSTRING */
    	/*ubVOID*/ 	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubINT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubFLOAT*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubBOOL*/	{	0,		0,		0,		
1,		0,		0,		0,		0	},
    	/*ubCUE*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubPHRASE*/{	0,		0,		0,		0,	
	0,		0,		0,		0	},
    	/*ubTIME*/	{	0,		0,		0,		
0,		0,		0,		0,		0	},
    	/*ubSTRING*/{	0,		0,		0,		0,	
	0,		0,		0,		0	}
      });

    
    tempCounter = 0;
  }
  
  private String upbeatTypeName( upbeatVal.Type type ) {
	  switch( type ){
	  case ubVOID:
		  return "void";
	  case ubINT:
		  return "int";
	  case ubFLOAT:
		  return "float";
	  case ubBOOL:
		  return "bool";
	  case ubCUE:
		  return "cue";
	  case ubPHRASE:
		  return "phrase";
	  case ubTIME:
		  return "time";
	  case ubSTRING:
		  return "string";
	  }
	  return "Unrecognized type";
  }
  
  private String javaTypeName( upbeatVal.Type type ) {
	  switch( type ){
	  case ubVOID:
		  return "void";
	  case ubINT:
		  return "int";
	  case ubFLOAT:
		  return "double";
	  case ubBOOL:
		  return "boolean";
	  case ubCUE:
		  return "Cue";
	  case ubPHRASE:
		  return "MusicPhrase";
	  case ubTIME:
		  return "int";
	  case ubSTRING:
		  return "String";
	  }
	  return "Unrecognized type";
  }
  
  /*private boolean is_cast_allowed( upbeatVal.Type oldType, upbeatVal.Type newT
ype ) {
	  return castTable[oldType.ordinal()][newType.ordinal()];
  }*/
  
  private String force_cast( upbeatVal.Type oldType, upbeatVal.Type newType ) {

	  if( oldType == null ) {
		  throw new Error("Attempting to cast from an unknown type");
	  }
	  if( newType == null ) {
		  throw new Error("Attempting to cast to an unknown type");
	  }

	  String cast = new String("");
	  short i = castTable[oldType.ordinal()][newType.ordinal()];
	  if( i == 0 ) {
	  // Disallow cast
		  yyerror("Illegal cast from " + upbeatTypeName(oldType) + " to 
" + upbeatTypeName(newType));
		  return cast;
	  }
	  else {
		  cast = cast.concat("(" + javaTypeName(newType) + ")");
	  }
	  
	  return cast;
  }
  
  private String perform_cast( upbeatVal.Type oldType, upbeatVal.Type newType ) 
{
	  if( oldType == null ) {
		  throw new Error("Attempting to cast from an unknown type");
	  }
	  if( newType == null ) {
		  throw new Error("Attempting to cast to an unknown type");
	  }
	  
	  String cast = new String("");
	  short i = castTable[oldType.ordinal()][newType.ordinal()];
	  switch( i ) {
	  // Disallow cast
	  case 0:
		  yyerror("Illegal cast from " + upbeatTypeName(oldType) + " to 
" + upbeatTypeName(newType));
		  return cast;
	  case 1:
		  yywarning("Casting from " + upbeatTypeName(oldType) + " to " +
 upbeatTypeName(newType));
	  case 2:
		  cast = cast.concat("(" + javaTypeName(newType) + ")");
		  return cast;
	  case 3:
		  return cast;
	  default:
		  throw new Error("Received illegal cast table value.");
	  }
  }
  
  // This is just a dummy function used for convenience...
  private upbeatVal CreateFunctionCall( upbeatVal funcName ) {
	  upbeatVal temp = new upbeatVal();
	  temp.listTypes = new LinkedList< upbeatVal.Type >();
	  temp.listExprs = new LinkedList< String >();
	  return CreateFunctionCall( funcName, temp );
  }
  
  private upbeatVal CreateFunctionCall( upbeatVal funcName, upbeatVal args ) {
	  
	  LinkedList< upbeatVal.Type > paramTypes = current_symbol_table.GetPara
mTypes( funcName.code );
	  LinkedList< upbeatVal.Type > argTypes = args.listTypes;
	  LinkedList< String > argExprs = args.listExprs;
	  
	  Iterator< upbeatVal.Type > paramIter = paramTypes.iterator();
	  Iterator< upbeatVal.Type > argIter = argTypes.iterator();
	  Iterator< String > exprIter = argExprs.iterator();
	  
	  String newCode = funcName.code;
	  newCode = newCode.concat("(");
	  
	  while( paramIter.hasNext() && argIter.hasNext() && exprIter.hasNext() 
) {
		  upbeatVal.Type argType = argIter.next();
		  upbeatVal.Type paramType = paramIter.next();
		  String expr = exprIter.next();
		  // If the argument and parameter have the same types, we don't
 need to cast
		  if( argType == paramType ) {
			  newCode = newCode.concat( expr );
		  }
		  else {
			  newCode = newCode.concat( perform_cast( argType, param
Type ) );
			  newCode = newCode.concat(expr);
		  }
			  
		  // If we still have more to go, we need to add in the commas!
		  if( paramIter.hasNext() || argIter.hasNext() || exprIter.hasNe
xt() )
			  newCode = newCode.concat(", ");
	  }
	  
	  if( paramIter.hasNext() || argIter.hasNext() || exprIter.hasNext() ) {
		  yyerror("Call to function " + funcName.code + " has incorrect 
number of arguments");
	  }
	  
	  newCode = newCode.concat(")");
	  
	  upbeatVal ret = new upbeatVal(newCode);
	  ret.type = current_symbol_table.GetFuncReturnType( funcName.code );
	  
	  return ret;
  }
  
  private upbeatVal apply_op (String op, String lcode, String rcode, 
		  upbeatVal.Type ltype, upbeatVal.Type rtype) {
	  upbeatVal p = new upbeatVal();
	  if(op == null) {
		  throw new Error("attempt to apply unknown operator");
	  }
	  if(lcode == null || rcode == null) {
		  throw new Error("attempt to apply operator " + op + " with cod
e missing");
	  }
	  if(ltype == null || rtype == null) {
		  throw new Error("attempt to apply operator " + op + " with cod
e missing");
	  }
	  short i = optable.get(op)[ltype.ordinal()][rtype.ordinal()];
	  switch(i) {
	  case 0:
		  yyerror("Operation " + op + " not allowed on type " + upbeatTy
peName(ltype) + " (left) and " +
				  upbeatTypeName(rtype) + " (right)");
		  break;
	  case 1:
		  p.code = lcode + " " + op + " " + rcode;
		  p.type = ltype;
		  break;
	  case 2:
		  p.code = lcode + " " + op + " " + rcode;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  case 3:
		  p.code = lcode + " = new " + javaTypeName(upbeatVal.Type.ubCUE
) + "(" + rcode + ")";
		  p.type = upbeatVal.Type.ubCUE;
		  break;
	  case 4:
		  p.code = lcode + " = new " + javaTypeName(upbeatVal.Type.ubPHR
ASE) + "(" + rcode + ")";
		  p.type = upbeatVal.Type.ubPHRASE;
		  break;
	  case 5:
		  p.code = lcode + " " + op + " Integer.toString(" + rcode + ")"
;
		  p.type = ltype;
		  break;
	  case 6:
		  p.code = "Integer.toString(" + lcode + ") " + op + " " + rcode
;
		  p.type = rtype;
		  break;
	  case 7:
		  p.code = lcode + " " + op + perform_cast(rtype, ltype) + rcode
;
		  p.type = ltype;
		  break;
	  case 8:
		  p.code = perform_cast(ltype, rtype) + lcode + " " + op + rcode
;
		  p.type = rtype;
		  break;
	  case 9:
		  p.code = lcode + " " + op + perform_cast(rtype, ltype) + rcode
;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  case 10:
		  p.code = perform_cast(ltype, rtype) + lcode + " " + op + rcode
;
		  p.type = upbeatVal.Type.ubBOOL;
		  break;
	  default:
		  yyerror("Undefined operation with given operator and types; th
is really shouldn't happen");
	  }
	  
	  // We're going to fully parenthesize our expressions.  However, we don
't want to parenthesize our
	  // assignment expressions or else we'll get code like: int (foo = 2);
	  if( !op.equals("=") )
		  p.code = "(" + p.code + ")";
	  return p;
  }

  private static long getNextTempName = 0;
  private static String getNextTempName()
  {
	  return "t_up_" + (getNextTempName++);
  }
  
  private static int musicianChannelCounter = 0;
  private static int getNextMusicianChannel() {
	  int chan = musicianChannelCounter++;
	  if(chan == 9) {
		  chan = musicianChannelCounter++;
	  }
	  if(chan > 15) {
		  throw new Error("Upbeat currently supports only 15 musicians t
o comply with MIDI restrictions");
	  }
	  return chan;
  }
  
  private String generate_conductor_code(String declarations, String statements,
 String functions) {
  	String compiled_code = new String("");
	compiled_code = compiled_code.concat(
			"package upbeat.sample;\n\n" +
			"import upbeat.Conductor;\n" +
			"import upbeat.Manager;\n" +
			"import upbeat.types.Cue;\n\n" +
			"public class CompiledConductor extends Conductor {\n" +
			" 	// Conductor member variable declarations will g
o here\n" +
			declarations +
			"\n" +
			"	CompiledConductor() {\n" +
			"		super();\n\n" +
			"		// Conductor member variable initializat
ions will go here\n" +
			statements +
			"\n" +
			"	}\n\n" +
			"	CompiledConductor( Manager man ) {\n" +
			"		super(man);\n" +
			"\n" +		
			"		// Conductor member variable initializat
ions will go here\n" +
			statements +
			"	}\n\n" +
			functions +
			"}");

	return compiled_code;
  }
  
  /* here's how we use the lexer/parser */
  public static void main(String args[]) throws IOException {
	  int parse_retval = -1;
	  parser yyparser = new parser(new FileReader(args[0]));
	  yyparser.yydebug = false;
	  
	  String destDir = "upbeat/sample/";
	  File fdestDir = new File(destDir);
	  try {
		  if(!fdestDir.exists()) {
			  fdestDir.mkdirs();
		  }
	  } catch (Exception e) {
		  System.err.println("Error creating destination directory: " + 
destDir);
	  }

	  System.out.println("Compiling Upbeat file:  " + args[0]);

	  parse_retval = yyparser.yyparse();
	  if(parse_retval == 0 && yyerrors == 0) {
		  try {
			  /* Write code files */
			  /* Application */
			  FileWriter fstream = new FileWriter(destDir + "Compile
dUpbeatApplication.java");
			  BufferedWriter out = new BufferedWriter(fstream);
			  System.out.println("Writing CompiledUpbeatApplication.
java ...");
			  out.write(yyparser.yyval.code);
			  out.close();
			  /* Conductor */
			  fstream = new FileWriter(destDir + "CompiledConductor.
java");
			  out = new BufferedWriter(fstream);
			  System.out.println("Writing CompiledConductor.java ...
");
			  out.write(yyparser.yyval.sval);
			  out.close();

			  /* Musicians */
			  Enumeration<String> k;
			  Hashtable<String, String> musicians = (Hashtable)yypar
ser.yyval.obj;
			  k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  fstream = new FileWriter(destDir + "Musician_"
 + key + ".java");
				  out = new BufferedWriter(fstream);
				  System.out.println("Writing Musician_" + key +
 ".java ...");
				  out.write(musicians.get(key));
				  out.close();
			  }
		  } catch (Exception e) {
			  System.err.println("Error in writing out code: " + e);
		  }
		  System.out.println("Successful parse with " + yyerrors + " err
ors and " + yywarnings + " warnings!\n Resulting code written to: " + fdestDir.g
etAbsolutePath() );
	  } else {
		  System.out.print("Parse error.  Returned " + parse_retval + " 
with " + yyerrors + " errors and " + yywarnings + " warnings.\n");
	  }
	  
	  System.exit(yyerrors);
  }
//#line 1584 "parser.java"
//###############################################################
// method: yylexdebug : check lexer state
//###############################################################
void yylexdebug(int state,int ch)
{
String s=null;
  if (ch < 0) ch=0;
  if (ch <= YYMAXTOKEN) //check index bounds
     s = yyname[ch];    //now get it
  if (s==null)
    s = "illegal-symbol";
  debug("state "+state+", reading "+ch+" ("+s+")");
}





//The following are now global, to aid in error reporting
int yyn;       //next next thing to do
int yym;       //
int yystate;   //current parsing state from state table
String yys;    //current token string


//###############################################################
// method: yyparse : parse input and execute indicated items
//###############################################################
int yyparse()
{
boolean doaction;
  init_stacks();
  yynerrs = 0;
  yyerrflag = 0;
  yychar = -1;          //impossible char forces a read
  yystate=0;            //initial state
  state_push(yystate);  //save it
  val_push(yylval);     //save empty value
  while (true) //until parsing is done, either correctly, or w/error
    {
    doaction=true;
    if (yydebug) debug("loop"); 
    //#### NEXT ACTION (from reduction table)
    for (yyn=yydefred[yystate];yyn==0;yyn=yydefred[yystate])
      {
      if (yydebug) debug("yyn:"+yyn+"  state:"+yystate+"  yychar:"+yychar);
      if (yychar < 0)      //we want a char?
        {
        yychar = yylex();  //get next token
        if (yydebug) debug(" next yychar:"+yychar);
        //#### ERROR CHECK ####
        if (yychar < 0)    //it it didn't work/error
          {
          yychar = 0;      //change it to default string (no -1!)
          if (yydebug)
            yylexdebug(yystate,yychar);
          }
        }//yychar<0
      yyn = yysindex[yystate];  //get amount to shift by (shift index)
      if ((yyn != 0) && (yyn += yychar) >= 0 &&
          yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
        {
        if (yydebug)
          debug("state "+yystate+", shifting to state "+yytable[yyn]);
        //#### NEXT STATE ####
        yystate = yytable[yyn];//we are in a new state
        state_push(yystate);   //save it
        val_push(yylval);      //push our lval as the input for next rule
        yychar = -1;           //since we have 'eaten' a token, say we need anot
her
        if (yyerrflag > 0)     //have we recovered an error?
           --yyerrflag;        //give ourselves credit
        doaction=false;        //but don't process yet
        break;   //quit the yyn=0 loop
        }

    yyn = yyrindex[yystate];  //reduce
    if ((yyn !=0 ) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
      {   //we reduced!
      if (yydebug) debug("reduce");
      yyn = yytable[yyn];
      doaction=true; //get ready to execute
      break;         //drop down to actions
      }
    else //ERROR RECOVERY
      {
      if (yyerrflag==0)
        {
        yyerror("syntax error");
        yynerrs++;
        }
      if (yyerrflag < 3) //low error count?
        {
        yyerrflag = 3;
        while (true)   //do until break
          {
          if (stateptr<0)   //check for under & overflow here
            {
            yyerror("stack underflow. aborting...");  //note lower case 's'
            return 1;
            }
          yyn = yysindex[state_peek(0)];
          if ((yyn != 0) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
            {
            if (yydebug)
              debug("state "+state_peek(0)+", error recovery shifting to state "
+yytable[yyn]+" ");
            yystate = yytable[yyn];
            state_push(yystate);
            val_push(yylval);
            doaction=false;
            break;
            }
          else
            {
            if (yydebug)
              debug("error recovery discarding state "+state_peek(0)+" ");
            if (stateptr<0)   //check for under & overflow here
              {
              yyerror("Stack underflow. aborting...");  //capital 'S'
              return 1;
              }
            state_pop();
            val_pop();
            }
          }
        }
      else            //discard this token
        {
        if (yychar == 0)
          return 1; //yyabort
        if (yydebug)
          {
          yys = null;
          if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
          if (yys == null) yys = "illegal-symbol";
          debug("state "+yystate+", error recovery discards token "+yychar+" ("+
yys+")");
          }
        yychar = -1;  //read another
        }
      }//end error recovery
    }//yyn=0 loop
    if (!doaction)   //any reason not to proceed?
      continue;      //skip action
    yym = yylen[yyn];          //get count of terminals on rhs
    if (yydebug)
      debug("state "+yystate+", reducing "+yym+" by rule "+yyn+" ("+yyrule[yyn]+
")");
    if (yym>0)                 //if count of rhs not 'nil'
      yyval = val_peek(yym-1); //get current semantic value
    yyval = dup_yyval(yyval); //duplicate yyval if ParserVal is used as semantic
 value
    switch(yyn)
      {
//########## USER-SUPPLIED ACTIONS ##########
case 1:
//#line 363 "upbeat-a.yacc"
{
			yyval = new upbeatVal("Generating compiled Upbeat code f
or " + val_peek(0).ival + " musicians.\n");
			
			String app_code = new String();
			
			app_code = app_code.concat("package upbeat.sample;\n\n" 
+
					"import upbeat.*;\n\n" +
					"public class CompiledUpbeatApplication 
implements UpbeatApplication {\n" +
					"	public static void main( String 
[] args ) {\n" +
"		// Right now, we're just going to assume that there is one input
 argument, and that it is a file name.\n" +
"		// When we implement real time, we will need to check to see if 
there is an additional flag to see\n" +
"		// whether we want real time or not.  The implementation of the 
Manager class we instantiate here will\n" +
"		// be dependent on whether or not we want to run in real time.  
However, for now, just assume it's always\n" +
"		// offline.\n" +
"\n" +		
"		// Create the Manager, Conductor, and Musician(s).\n" +
"		Manager manager;\n" +
"		//if( realtime )\n" +
"		// manager = new RealTimeManager();\n" +
"		//else\n" +
"		manager = new OfflineManager();\n" +
"\n" +		
"		TempoOptions tempoOptions = new CompiledTempoOptions();\n" +
"		Conductor conductor = new CompiledConductor(manager);\n");
			
			Hashtable<String, String> musicians;
			Enumeration<String> k;
			/* TODO: clean up the way we assign musician code*/
			musicians = (Hashtable)val_peek(0).obj;
			k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  app_code = app_code.concat("\t\tMusician " + k
ey + " = new Musician_" + key + "();\n");
			  }
			
			app_code = app_code.concat(
					"		// Set the manager up wi
th the input file, the Conductor, and the Musician(s)\n" +
"		if( args.length < 1 ) {\n" +
"			System.out.println(\"Warning: No input source supplied!\
");\n" +
"		}\n" +
"		else {\n" +
"			String inputname = args[0];\n" +
"			if( !manager.SetInputSource(inputname) ) {\n" +
"				System.out.printf(\"Error: Could not open source
:%s\", inputname);\n" +
"			}\n" +
"		}\n" +
"\n" +			
"		manager.SetTempoOptions(tempoOptions);\n" +
"		manager.SetConductor(conductor);\n" +
"\n" +				
"		// We're going to need to have an individual AddMusician call fo
r each Musician\n");
			
			k = musicians.keys();
			  while(k != null && k.hasMoreElements()) {
				  String key = k.nextElement();
				  app_code = app_code.concat("\t\tmanager.AddMus
ician(" + key + ");\n");
			  }

			  app_code = app_code.concat(
"		// Note, if we're writing the output to a MIDI file on disk we m
ight want to have a way of\n" +
"		// providing an output file name.\n" +
"		manager.MakeSomeMusic();\n" +
"	}\n" +
"}\n\n");

			app_code = app_code.concat(val_peek(2).code);
			
			String conductor_code = new String(val_peek(1).code);

			/*System.out.println(">>>>>>>>>>>>> CompiledUpbeatApplic
ation.java >>>>>>>>>>>>>>>>>\n\n" + app_code +*/
			/*		"\n>>>>>>>>>>>>> CompiledConductor.java 
>>>>>>>>>>>>>>>>>\n\n" + conductor_code);*/
			k = musicians.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
			/*	System.out.println(">>>>>>>>>>>>> Musician_" + k
ey + ".java >>>>>>>>>>>>>>>>>\n\n" + musicians.get(key) + "\n\n");*/
			}
			/* 1. Construct CompiledUpbeatApplication:
			 * 	a. iterate through musicians by NAME and constru
ct Musician NAME = new Musician_NAME()
			 * 	b. also iterate through and do manager.addMusici
an(NAME);
			 *  c. stick the tempo options on the end!
			 * 2. Construct CompiledConductor
			 *  a. stick in 
			 */
			if(current_symbol_table.numSymbols() > 0) {
				System.err.println("Warning: global symbol table
 has symbols; this is unusual in Upbeat:\n" + current_symbol_table.toString());
			}
			yyval = new upbeatVal(app_code);
			yyval.sval = conductor_code;
			yyval.obj = new Hashtable<String, String>();
			k = musicians.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
				((Hashtable<String,String>)yyval.obj).put(key, m
usicians.get(key));
			}
    	}
break;
case 2:
//#line 462 "upbeat-a.yacc"
{ yyval = new upbeatVal("class CompiledTempoOptions extends TempoOptions {\n" +
    	"\tCompiledTempoOptions(){\n\t\t// This is where and how we set the head
er information\n" +
    	val_peek(1).code + val_peek(0).code +
    	"\t}\n}\n"); }
break;
case 3:
//#line 467 "upbeat-a.yacc"
{ yyval = new upbeatVal("class CompiledTempoOptions extends TempoOptions {\n" +
	    "\tCompiledTempoOptions(){\n\t\t// This is where and how we set the 
header information\n" +
	    val_peek(0).code + val_peek(1).code +
	    "\t}\n}\n"); }
break;
case 4:
//#line 475 "upbeat-a.yacc"
{ yyval = new upbeatVal("\t\tsuper.TIME_SIGNATURE_TOP = " + val_peek(3).ival +
    						 ";\n\t\tsuper.TIME_SIGNATURE_BO
TTOM = " + val_peek(1).ival + ";\n"); }
break;
case 5:
//#line 481 "upbeat-a.yacc"
{
    	if (val_peek(1).ival < 1 || val_peek(1).ival > 1000) {
    	/*TODO: what are the legal tempo values?*/
    	/*TODO: define a warning and an error function for parsing? lexing?*/
    		System.err.print("Warning: TEMPO must be an integer between 1 an
d 1000, representing beats per minute.  " +
    		"Defaulting to 100 bpm.\n");
    		val_peek(1).ival = 100;
    	}
    	yyval = new upbeatVal("\t\tsuper.TEMPO = " + val_peek(1).ival + ";\n"); 
}
break;
case 6:
//#line 494 "upbeat-a.yacc"
{
    		SymbolTable t = new SymbolTable(current_symbol_table);
    		current_symbol_table = t;
    	}
break;
case 7:
//#line 499 "upbeat-a.yacc"
{
    	yyval = new upbeatVal(val_peek(1).code);
    	current_symbol_table = current_symbol_table.parent;
    		/* 
    		 * Write out CompiledConductor class with:
    		 * 1. Declarations for all local variables in Upbeat Conductor {
} block
    		 * 2. Constructors for CompiledConductor class that initialize a
ll local Upbeat variables
    		 * 3. All functions defined in Conductor {} block
    		 * 4. 
    		 */
    	}
break;
case 8:
//#line 514 "upbeat-a.yacc"
{
    	String declarations = new String("");
    	/* there are no declarations*/
    	String statements = new String("");
    	/* there are no statements*/
    	String functions = new String("");
    	functions = functions.concat(val_peek(0).code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	yyval = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
break;
case 9:
//#line 530 "upbeat-a.yacc"
{
    	String declarations = new String("");
    	/* there are no declarations*/
    	String statements = new String(val_peek(1).code);
    	String functions = new String("");
    	functions = functions.concat(val_peek(0).code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	yyval = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
break;
case 10:
//#line 545 "upbeat-a.yacc"
{
    	String declarations = new String(val_peek(1).code);
    	String statements = new String("");
    	/* there are no statements*/
    	String functions = new String(val_peek(0).code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	yyval = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
break;
case 11:
//#line 559 "upbeat-a.yacc"
{
    	String declarations = new String(val_peek(2).code);
    	String statements = new String(val_peek(1).code);
    	String functions = new String(val_peek(0).code);
    	
    	String compiled_code = generate_conductor_code(declarations, statements,
 functions);

    	yyval = new upbeatVal(compiled_code);
    	/* TODO: Check to make sure there's at least 1 Conduct() method
    	 * 
    	 */
    }
break;
case 12:
//#line 575 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("{ }");
    	}
break;
case 13:
//#line 579 "upbeat-a.yacc"
{
    		/* No Symbol table needed, since there are no declarations.*/
    		yyval = new upbeatVal("{\n" + val_peek(1).code + " }\n");
    	}
break;
case 14:
//#line 584 "upbeat-a.yacc"
{ /* start new symbol table:*/
    		/*  1. create new symbol table new_table*/
    		/*  2. assign current_sym_table to be its parent*/
    		/*  3. assign new_table to current_sym_table*/
  			SymbolTable t = new SymbolTable(current_symbol_table);
  			current_symbol_table = t;
		}
break;
case 15:
//#line 592 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("{\n" + val_peek(2).code + "\n" + val_peek
(1).code + " }\n");
    	  	current_symbol_table = current_symbol_table.parent;
    	}
break;
case 16:
//#line 600 "upbeat-a.yacc"
{
    	yyval = new upbeatVal(val_peek(0).code);
    }
break;
case 17:
//#line 604 "upbeat-a.yacc"
{
    	yyval = new upbeatVal(val_peek(1).code + val_peek(0).code);
    }
break;
case 18:
//#line 611 "upbeat-a.yacc"
{
			/*System.out.println(">>>>>>> RESOLVED NEW STATEMENT: CO
MPOUND <<<<<<<<\n");*/
			/*		">>> " + $1.code + " <<<");*/
    	}
break;
case 19:
//#line 616 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.type = val_peek(0).type;
		}
break;
case 20:
//#line 621 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
		}
break;
case 21:
//#line 625 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
		}
break;
case 22:
//#line 629 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.type = val_peek(0).type;
			/*System.out.println(">>>>>>> RESOLVED NEW STATEMENT: FL
OW CONTROL <<<<<<<<");*/
		}
break;
case 25:
//#line 640 "upbeat-a.yacc"
{
    	yyval = new upbeatVal(val_peek(0).code);
    	yyval.type = val_peek(0).type;
    }
break;
case 26:
//#line 649 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("return;");
    		current_symbol_table.Returns();
    	}
break;
case 27:
//#line 654 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("return " + perform_cast( val_peek(1).type
, current_symbol_table.GetCurrentReturnType() ) + val_peek(1).code + ";");
    		current_symbol_table.Returns();
    	}
break;
case 28:
//#line 662 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(1).code + ";\n");
    	}
break;
case 29:
//#line 666 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(";\n");
    	}
break;
case 30:
//#line 673 "upbeat-a.yacc"
{
	    	yyval = new upbeatVal( val_peek(1).code );
	    }
break;
case 31:
//#line 680 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    	}
break;
case 32:
//#line 684 "upbeat-a.yacc"
{
	    	String newCode = new String("");
	    	newCode = newCode.concat( val_peek(1).code );
	    	newCode = newCode.concat( "else " );
	    	newCode = newCode.concat( val_peek(0).code );
	    	
	    	yyval = new upbeatVal( newCode );
	    }
break;
case 33:
//#line 696 "upbeat-a.yacc"
{
	    	String newCode = new String("if(");
	    	newCode = newCode.concat(val_peek(2).code);
	    	newCode = newCode.concat(") {\n");
	    	newCode = newCode.concat( val_peek(0).code );
	    	newCode = newCode.concat( "}\n" );
	    	
	    	yyval = new upbeatVal( newCode );
	    }
break;
case 34:
//#line 709 "upbeat-a.yacc"
{
		if (val_peek(1).type == upbeatVal.Type.ubBOOL) {
			String newCode = new String ("while (");
			newCode = newCode.concat (val_peek(1).code);
			newCode = newCode.concat (") {\n");
			yyval = new upbeatVal( newCode );
    	}
		else {
			String ub_REPEATlimit = new String( getNextTempName() );
 /* need to get the name to use later*/
			String newCode = new String("int " + ub_REPEATlimit + " 
= " + perform_cast(val_peek(1).type, upbeatVal.Type.ubINT) + val_peek(1).code  +
 ";\n");
			/* now generate for loop*/
    		newCode = newCode.concat ("for (int ub_REPEATscroll = 1; ub_REPE
ATscroll <= " + ub_REPEATlimit + "; ub_REPEATscroll++ ) {\n");
    		yyval = new upbeatVal( newCode );
		}
	}
break;
case 35:
//#line 725 "upbeat-a.yacc"
{
    	yyval = new upbeatVal( val_peek(1).code + val_peek(0).code + " }\n" );
    }
break;
case 36:
//#line 733 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 37:
//#line 738 "upbeat-a.yacc"
{
    		/* If we haven't checked to make sure we've defined the stuff us
ed in the*/
    		/* post fix expression, we need to do the check now!*/
    		if( !val_peek(2).definitionCheck ) {
    			if( current_symbol_table.GetDefLine( val_peek(2).sval ) 
== -1 ) {
    				yyerror("Identifier: " + val_peek(2).sval + " is
 undefined");
    				if(val_peek(2).sval.toLowerCase().equals("return
")) {
    					yyerror("Perhaps you meant \"Return\" wi
th a capital \"R\"?");
    				} else if (val_peek(2).sval.toLowerCase().equals
("input")) {
    					yyerror("Perhaps you meant \"input\", al
l lowercase?");
    				} /* else no help*/
    			}
    		}

			yyval = apply_op("=", val_peek(2).code, val_peek(0).code
, val_peek(2).type, val_peek(0).type);
			/* TODO: (optional) mark in symbol table that it's been 
assigned */
      	}
break;
case 38:
//#line 759 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 39:
//#line 767 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 40:
//#line 772 "upbeat-a.yacc"
{
			yyval = apply_op("||", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 41:
//#line 779 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 42:
//#line 784 "upbeat-a.yacc"
{
			yyval = apply_op("&&", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 43:
//#line 791 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 44:
//#line 796 "upbeat-a.yacc"
{
			yyval = apply_op("==", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 45:
//#line 800 "upbeat-a.yacc"
{
			yyval = apply_op("!=", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 46:
//#line 807 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 47:
//#line 812 "upbeat-a.yacc"
{
			yyval = apply_op("<", val_peek(2).code, val_peek(0).code
, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 48:
//#line 816 "upbeat-a.yacc"
{
			yyval = apply_op(">", val_peek(2).code, val_peek(0).code
, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 49:
//#line 820 "upbeat-a.yacc"
{
			yyval = apply_op("<=", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 50:
//#line 824 "upbeat-a.yacc"
{
			yyval = apply_op(">=", val_peek(2).code, val_peek(0).cod
e, val_peek(2).type, val_peek(0).type);
	  	}
break;
case 51:
//#line 831 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 52:
//#line 836 "upbeat-a.yacc"
{
    		if( val_peek(2).type != upbeatVal.Type.ubINT && val_peek(2).type
 != upbeatVal.Type.ubFLOAT ) {
    			yyerror("Expression to left of 'in' keyword on line does
 not evaluate to an " +
    					upbeatTypeName(upbeatVal.Type.ubINT) + "
 or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT) + ".");
    		}
    		
	    	upbeatVal.Type tempType;
	    	if( val_peek(2).type == upbeatVal.Type.ubINT && 
	    	    val_peek(0).rangeLeftType == upbeatVal.Type.ubINT &&
	    	    val_peek(0).rangeRightType == upbeatVal.Type.ubINT )
	    		tempType = upbeatVal.Type.ubINT;
	    	else
	    		tempType = upbeatVal.Type.ubFLOAT;
	    	
	    	/* Lets get our additive expression code right*/
	    	/* We need to make sure to cast it if need be...*/
	    	String addExpr = new String("(");
	    	if( val_peek(2).type != tempType )
	    		addExpr = addExpr.concat( "(" + javaTypeName(tempType) +
 ")" );
	    	addExpr = addExpr.concat(val_peek(2).code);
	    	addExpr = addExpr.concat(")");
	    	
	    	/* Do the same for our right and left expressions in our*/
	    	/* range specifier*/
	    	String leftExpr = new String("(");
	    	if( val_peek(0).rangeLeftType != tempType )
	    		leftExpr = leftExpr.concat( "(" + javaTypeName(tempType)
 + ")" );
	    	leftExpr = leftExpr.concat(val_peek(0).rangeLeft);
	    	leftExpr = leftExpr.concat(")");
	    	
	    	String rightExpr = new String("(");
	    	if( val_peek(0).rangeRightType != tempType )
	    		rightExpr = rightExpr.concat( "(" + javaTypeName(tempTyp
e) + ")" );
	    	rightExpr = rightExpr.concat(val_peek(0).rangeRight);
	    	rightExpr = rightExpr.concat(")");
	    	
	    	/* Finally, we need to make sure our operations are correct*/
	    	/* depending on whether the range is open or closed.*/
	    	String leftOp;
	    	if( val_peek(0).leftOpen )
	    		leftOp = new String(" > ");
	    	else
	    		leftOp = new String(" >= ");
	    	
	    	String rightOp;
	    	if( val_peek(0).rightOpen )
	    		rightOp = new String(" < ");
	    	else
	    		rightOp = new String(" <= ");
	    	
	    	String newCode = new String("((");
	    	newCode = newCode.concat( addExpr + leftOp + leftExpr );
	    	newCode = newCode.concat( ") && (");
	    	newCode = newCode.concat( addExpr + rightOp + rightExpr );
	    	newCode = newCode.concat("))");
	    	
	    	yyval = new upbeatVal(newCode);
	    	yyval.type = upbeatVal.Type.ubBOOL;
	    }
break;
case 53:
//#line 899 "upbeat-a.yacc"
{
	    	if( val_peek(3).type != upbeatVal.Type.ubINT && 
	    		val_peek(3).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( val_peek(1).type != upbeatVal.Type.ubINT && 
	    		val_peek(1).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	yyval = new upbeatVal();
	    	yyval.rangeLeft = new String( val_peek(3).code );
	    	yyval.rangeRight = new String( val_peek(1).code );
	    	yyval.leftOpen = true;
	    	yyval.rightOpen = true;
	    	yyval.rangeLeftType = val_peek(3).type;
	    	yyval.rangeRightType = val_peek(1).type;
	    }
break;
case 54:
//#line 920 "upbeat-a.yacc"
{
	    	if( val_peek(3).type != upbeatVal.Type.ubINT && 
	    		val_peek(3).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( val_peek(1).type != upbeatVal.Type.ubINT && 
	    		val_peek(1).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	yyval = new upbeatVal();
	    	yyval.rangeLeft = new String( val_peek(3).code );
	    	yyval.rangeRight = new String( val_peek(1).code );
	    	yyval.leftOpen = false;
	    	yyval.rightOpen = true;
	    	yyval.rangeLeftType = val_peek(3).type;
	    	yyval.rangeRightType = val_peek(1).type;
	    }
break;
case 55:
//#line 941 "upbeat-a.yacc"
{
	    	if( val_peek(3).type != upbeatVal.Type.ubINT && 
	    		val_peek(3).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( val_peek(1).type != upbeatVal.Type.ubINT && 
	    		val_peek(1).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	yyval = new upbeatVal();
	    	yyval.rangeLeft = new String( val_peek(3).code );
	    	yyval.rangeRight = new String( val_peek(1).code );
	    	yyval.leftOpen = true;
	    	yyval.rightOpen = false;
	    	yyval.rangeLeftType = val_peek(3).type;
	    	yyval.rangeRightType = val_peek(1).type;
	    }
break;
case 56:
//#line 962 "upbeat-a.yacc"
{
	    	if( val_peek(3).type != upbeatVal.Type.ubINT && 
	    		val_peek(3).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Left half of range specifier does not evaluate 
to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	if( val_peek(1).type != upbeatVal.Type.ubINT && 
	    		val_peek(1).type != upbeatVal.Type.ubFLOAT ) {
	    		yyerror("Right half of range specifier does not evaluate
 to an " 
	    				+ upbeatTypeName(upbeatVal.Type.ubINT) +
 " or a " + upbeatTypeName(upbeatVal.Type.ubFLOAT));
	    	}
	    	
	    	yyval = new upbeatVal();
	    	yyval.rangeLeft = new String( val_peek(3).code );
	    	yyval.rangeRight = new String( val_peek(1).code );
	    	yyval.leftOpen = false;
	    	yyval.rightOpen = false;
	    	yyval.rangeLeftType = val_peek(3).type;
	    	yyval.rangeRightType = val_peek(1).type;
	    }
break;
case 57:
//#line 986 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 58:
//#line 991 "upbeat-a.yacc"
{
    		yyval = apply_op("+", val_peek(2).code, val_peek(0).code, val_pe
ek(2).type, val_peek(0).type);
    	}
break;
case 59:
//#line 995 "upbeat-a.yacc"
{
	    	yyval = apply_op("-", val_peek(2).code, val_peek(0).code, val_pe
ek(2).type, val_peek(0).type);
	    }
break;
case 60:
//#line 1002 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.type = val_peek(0).type;
		}
break;
case 61:
//#line 1007 "upbeat-a.yacc"
{
	    	yyval = apply_op("*", val_peek(2).code, val_peek(0).code, val_pe
ek(2).type, val_peek(0).type);
	    }
break;
case 62:
//#line 1011 "upbeat-a.yacc"
{
    		yyval = apply_op("/", val_peek(2).code, val_peek(0).code, val_pe
ek(2).type, val_peek(0).type);
	    }
break;
case 63:
//#line 1015 "upbeat-a.yacc"
{
			yyval = apply_op("%", val_peek(2).code, val_peek(0).code
, val_peek(2).type, val_peek(0).type);
	    }
break;
case 64:
//#line 1022 "upbeat-a.yacc"
{
    		yyval = new upbeatVal( val_peek(0).code );
    		yyval.type = val_peek(0).type;
    		
    		/* If we haven't checked to make sure we've defined the stuff us
ed in the*/
    		/* post fix expression, we need to do the check now!*/
    		if( !val_peek(0).definitionCheck ) {
    			if( current_symbol_table.GetDefLine( val_peek(0).sval ) 
== -1 ) {
    				yyerror("Identifier: " + val_peek(0).sval + " is
 undefined");
    				if(val_peek(0).sval.toLowerCase().equals("return
")) {
    					yyerror("Perhaps you meant \"Return\" wi
th a capital \"R\"?");
    				} else if (val_peek(0).sval.toLowerCase().equals
("input")) {
    					yyerror("Perhaps you meant \"input\", al
l lowercase?");
    				} /* else no help*/
    			}
    		}
    			
    	}
break;
case 65:
//#line 1041 "upbeat-a.yacc"
{
	    	yyval = new upbeatVal( val_peek(1).code + val_peek(0).code );
	    	yyval.type = val_peek(0).type;
	    	
	    	switch( val_peek(1).unaryOp ) {
	    	case uopPLUS:
	    		switch( val_peek(0).type ) {
	    		case ubVOID:
	    		case ubBOOL:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '+' 
to an expression of type: "
	    					+ upbeatTypeName(val_peek(0).typ
e));
	    		}
	    		break;
	    	case uopMINUS:
	    		switch( val_peek(0).type ) {
	    		case ubVOID:
	    		case ubBOOL:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '-' 
to an expression of type: "
	    					+ upbeatTypeName(val_peek(0).typ
e));
	    		}
	    		break;
	    	case uopNOT:
	    		switch( val_peek(0).type ) {
	    		case ubVOID:
	    		case ubINT:
	    		case ubFLOAT:
	    		case ubCUE:
	    		case ubPHRASE:
	    		case ubTIME:
	    		case ubSTRING:
	    			yyerror("Attempting to apply unary operator '!' 
to an expression of type: "
	    					+ upbeatTypeName(val_peek(0).typ
e));
	    		}
	    		break;
	    	}
	    }
break;
case 66:
//#line 1084 "upbeat-a.yacc"
{
    		String newCode = new String( force_cast(val_peek(0).type, val_pe
ek(2).type) );
    		newCode = newCode.concat( val_peek(0).code );
	    	yyval = new upbeatVal(newCode);
	    	yyval.type = val_peek(2).type;
	    }
break;
case 67:
//#line 1100 "upbeat-a.yacc"
{
    		yyval = new upbeatVal( val_peek(0).code );
    		yyval.type = val_peek(0).type;
    		yyval.sval = val_peek(0).sval;
    		yyval.alreadyPostFixed = false;
    		
    		/* Up the line we might need to do a definition check*/
    		yyval.definitionCheck = val_peek(0).definitionCheck;
    	}
break;
case 68:
//#line 1110 "upbeat-a.yacc"
{
	    	yyval = new upbeatVal( val_peek(0).code );
	    	yyval.type = val_peek(0).type;
	    	
	    	/* Don't think we need this here*/
	    	/*$$.sval = $1.sval;*/
	    	
	    	/* We never want to add a postfix operator after an input expres
sion*/
	    	yyval.alreadyPostFixed = true;
	    	yyval.definitionCheck = true;
	    }
break;
case 69:
//#line 1122 "upbeat-a.yacc"
{
	    	if( val_peek(2).alreadyPostFixed )
				yyerror("Chaining of postfix expressions not all
owed");
		    
		    /* Now let's do the type checking!*/
			if( current_symbol_table.GetFuncDefLine( val_peek(2).cod
e ) == -1 ) {
				yyerror("Function: " + val_peek(2).sval + " is u
ndefined");
				yyval = val_peek(2);
			}
			else
				yyval = CreateFunctionCall( val_peek(2) );
			
			
			yyval.alreadyPostFixed = true;
			yyval.definitionCheck = true;
	    }
break;
case 70:
//#line 1139 "upbeat-a.yacc"
{
	    	if( val_peek(3).alreadyPostFixed )
				yyerror("Chaining of postfix expressions not all
owed");

	    	/* Now let's do the type checking!*/
			if( current_symbol_table.GetFuncDefLine( val_peek(3).cod
e ) == -1 ) {
				yyerror("Function: " + val_peek(3).sval + " is u
ndefined");
				yyval = val_peek(3);
			}
			else
				yyval = CreateFunctionCall( val_peek(3), val_pee
k(1) );
			
			yyval.alreadyPostFixed = true;
	    	yyval.definitionCheck = true;
	    }
break;
case 71:
//#line 1155 "upbeat-a.yacc"
{
    		if( val_peek(2).type != upbeatVal.Type.ubCUE ) {
    			yyerror("Expression must be of type " + upbeatTypeName(u
pbeatVal.Type.ubCUE) + " to have a data member");
    		}
	    	yyval = new upbeatVal( val_peek(2).code + ".data" );
	    	yyval.type = upbeatVal.Type.ubINT;
	    	yyval.alreadyPostFixed = true;
	    	/* Now let's do the type checking!*/
	    	if( !val_peek(2).definitionCheck ) {
				if( current_symbol_table.GetDefLine( val_peek(2)
.sval ) == -1 ) {
					yyerror("Using " + val_peek(2).sval + " 
without having declared it");
				}
	    	}
			yyval.sval = val_peek(2).sval;
	    	yyval.definitionCheck = true;
	    }
break;
case 72:
//#line 1175 "upbeat-a.yacc"
{
    		if( !current_symbol_table.inConductorFunc ) {
    			yyerror( "Attempting to use reserved word input while no
t in a Conductor function" );
    		}
			String newCode = new String("");
			newCode = newCode.concat(val_peek(5).code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("ValueAt(");
			newCode = newCode.concat( perform_cast(val_peek(1).type,
 upbeatVal.Type.ubINT) );
			newCode = newCode.concat( val_peek(1).code );
			newCode = newCode.concat(")");
			
			if( val_peek(1).type != upbeatVal.Type.ubINT && val_peek
(1).type != upbeatVal.Type.ubTIME ) {
				yyerror(" Expression:\n" + val_peek(1).code + "\
nmust be either of type " + upbeatTypeName(upbeatVal.Type.ubINT) + " or "
						+ upbeatTypeName(upbeatVal.Type.
ubTIME));
			}
			
			yyval = new upbeatVal( newCode );
			yyval.type = upbeatVal.Type.ubFLOAT;
		}
break;
case 73:
//#line 1196 "upbeat-a.yacc"
{
    		if( !current_symbol_table.inConductorFunc ) {
				yyerror( "Attempting to use reserved word input 
while not in a Conductor function" );
			}
	    	String newCode = new String("");
			newCode = newCode.concat(val_peek(2).code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("CurrentValue()");
			yyval = new upbeatVal( newCode );
			yyval.type = upbeatVal.Type.ubFLOAT;
		}
break;
case 74:
//#line 1208 "upbeat-a.yacc"
{
    		if( !current_symbol_table.inConductorFunc ) {
				yyerror( "Attempting to use reserved word input 
while not in a Conductor function" );
			}
	    	String newCode = new String("");
			newCode = newCode.concat(val_peek(2).code);
			newCode = newCode.concat(".");
			newCode = newCode.concat("GetMore()");
			yyval = new upbeatVal( newCode );
			yyval.type = upbeatVal.Type.ubBOOL;
		}
break;
case 75:
//#line 1223 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.sval = val_peek(0).sval;
    		yyval.type = current_symbol_table.GetType(val_peek(0).sval);
    		yyval.definitionCheck = false;
    	}
break;
case 76:
//#line 1230 "upbeat-a.yacc"
{
    		if( !current_symbol_table.inCueResponse ) {
    			yyerror("Attempting to use " + val_peek(0).code + " whil
e not in a cue response");
    		}
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.sval = val_peek(0).sval;
    		yyval.type = upbeatVal.Type.ubCUE;
    		yyval.definitionCheck = true;
	    }
break;
case 77:
//#line 1240 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.type = val_peek(0).type;
    		yyval.sval = val_peek(0).code;
    		yyval.definitionCheck = true;
    	}
break;
case 78:
//#line 1247 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).sval);
    		yyval.sval = val_peek(0).code;
    		/* Agreed, that's a little confusing.*/
    		yyval.type = val_peek(0).type;
    		yyval.definitionCheck = true;
    	}
break;
case 79:
//#line 1255 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("(" + val_peek(1).code + ")");
    		yyval.type = val_peek(1).type;
    		yyval.sval = val_peek(2).code;
    		yyval.definitionCheck = true;
    	}
break;
case 80:
//#line 1265 "upbeat-a.yacc"
{
    		yyval = new upbeatVal("+");
    		yyval.unaryOp = upbeatVal.UnaryOp.uopPLUS;
    	}
break;
case 81:
//#line 1270 "upbeat-a.yacc"
{
			yyval = new upbeatVal("-");
			yyval.unaryOp = upbeatVal.UnaryOp.uopMINUS;
		}
break;
case 82:
//#line 1275 "upbeat-a.yacc"
{
			yyval = new upbeatVal("!");
			yyval.unaryOp = upbeatVal.UnaryOp.uopNOT;
		}
break;
case 83:
//#line 1283 "upbeat-a.yacc"
{
    		yyval = val_peek(0);
    		yyval.listTypes = new LinkedList<upbeatVal.Type>();
    		yyval.listTypes.add(val_peek(0).type);
    		yyval.listExprs = new LinkedList<String>();
    		yyval.listExprs.add(val_peek(0).code);
    	}
break;
case 84:
//#line 1291 "upbeat-a.yacc"
{
			/* We're not actually going to use this code...*/
			yyval = new upbeatVal( val_peek(2).code + ", " + val_pee
k(0).code );
			
			/* We need to build up a list of expression codes and ty
pes*/
			/* so we can do type checking and casting at the postfix
_expression*/
			/* level of the grammar*/
			yyval.listTypes = val_peek(2).listTypes;
			yyval.listTypes.add(val_peek(0).type);
			yyval.listExprs = val_peek(2).listExprs;
			yyval.listExprs.add(val_peek(0).code);
		}
break;
case 85:
//#line 1307 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(0).code );
			yyval.listTypes = new LinkedList< upbeatVal.Type >();
			yyval.listTypes.add( val_peek(0).type );
		}
break;
case 86:
//#line 1313 "upbeat-a.yacc"
{
			yyval = new upbeatVal( val_peek(2).code + ", " + val_pee
k(0).code );
			yyval.listTypes = val_peek(2).listTypes;
			yyval.listTypes.add( val_peek(0).type );
		}
break;
case 87:
//#line 1323 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(1).code + ";");
    	}
break;
case 88:
//#line 1327 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(2).code + "\n" + val_peek(1).code
 + ";");
    	}
break;
case 89:
//#line 1334 "upbeat-a.yacc"
{
    		/* First, check if variable is declared already; if not, add to 
symbol table */
    		if(current_symbol_table.GetType(val_peek(0).sval) == null) {
    			current_symbol_table.AddSymbol(val_peek(0).sval, val_pee
k(1).type, lexer.current_line());
    		} else {
    			yyerror("Variable " + val_peek(0).sval + " already defin
ed on line " +
    					current_symbol_table.GetDefLine(val_peek
(0).sval) + " as an " +
    					current_symbol_table.GetType(val_peek(0)
.sval));
    		}
    		
    		/* Assignment type checking and code generation */
    		if(val_peek(0).obj instanceof String) {
    			/* Need to do assignment*/
    			yyval = apply_op("=", val_peek(0).code, (String)val_peek
(0).obj, val_peek(1).type, val_peek(0).type);
    		} else {
    			yyval = new upbeatVal(val_peek(0).code);
    		}
    		yyval.code = val_peek(1).code + " " + yyval.code;
    		yyval.type = val_peek(1).type;
    	}
break;
case 90:
//#line 1358 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    		yyval.sval = val_peek(0).sval;
    	}
break;
case 91:
//#line 1363 "upbeat-a.yacc"
{
    		/* NOTE THAT ASSIGNMENT TYPE CHECKING OCCURS UP AT DECLARATION. 
*/
    		/* TODO: (optional) mark in symbol table that it's been assigned
 */
    		yyval = new upbeatVal(val_peek(0).type);
    		yyval.sval = val_peek(2).sval;
    		yyval.code = val_peek(2).code;
    		yyval.obj = new String(val_peek(0).code);
    	}
break;
case 92:
//#line 1375 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubINT);
    		yyval.code = javaTypeName(upbeatVal.Type.ubINT);
    	}
break;
case 93:
//#line 1380 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubFLOAT);
    		yyval.code = javaTypeName(upbeatVal.Type.ubFLOAT);
    	}
break;
case 94:
//#line 1385 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubBOOL);
    		yyval.code = javaTypeName(upbeatVal.Type.ubBOOL);
    	}
break;
case 95:
//#line 1390 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubCUE);
    		yyval.code = javaTypeName(upbeatVal.Type.ubCUE);
    	}
break;
case 96:
//#line 1395 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubPHRASE);
    		yyval.code = javaTypeName(upbeatVal.Type.ubPHRASE);
    	}
break;
case 97:
//#line 1400 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(upbeatVal.Type.ubTIME);
    		yyval.code = javaTypeName(upbeatVal.Type.ubTIME);
    	}
break;
case 98:
//#line 1408 "upbeat-a.yacc"
{
    	yyval = new upbeatVal(val_peek(0).code);
	}
break;
case 99:
//#line 1412 "upbeat-a.yacc"
{
		yyval = new upbeatVal(val_peek(1).code + val_peek(0).code);
	}
break;
case 100:
//#line 1419 "upbeat-a.yacc"
{	
			/* First, check if variable is declared already; if not,
 add to symbol table*/
    		if(current_symbol_table.GetFuncReturnType(val_peek(2).code) == n
ull) {
    			FunctionType fType = new FunctionType();
    			fType.SetReturnType( upbeatVal.Type.ubVOID );
    			current_symbol_table.AddFuncSymbol( val_peek(2).code, fT
ype, lexer.current_line());
    		} else {
    			yyerror("Function " + val_peek(2).sval + " already defin
ed on line " +
    					current_symbol_table.GetFuncDefLine(val_
peek(2).code));
    		}
    		
    		SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = val_peek(2).code;
		}
break;
case 101:
//#line 1436 "upbeat-a.yacc"
{
			String funcode = new String("\n");
    		yyval = new upbeatVal(upbeatVal.Type.ubVOID);
    		if(val_peek(4).sval.equals("Conduct")) {
    			funcode = funcode.concat("protected ");
    		}
    		funcode = funcode.concat("void " + val_peek(4).code + "() " + va
l_peek(0).code);
    		yyval.code = funcode;
    		current_symbol_table = current_symbol_table.parent;
		}
break;
case 102:
//#line 1447 "upbeat-a.yacc"
{	
    		/* We need a new symbol table to scope arguments to the function
.*/
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = val_peek(1).code;
			
			/* What follows is kind of weird.*/
			
			/* Basically, we need to create a new symbol table that 
corresponds with the code*/
			/* immediately inside this function call.  We want the p
arameters in the parameter_list*/
			/* below to be scoped only to the function.  However, we
 need to know what types the parameters*/
			/* are in order to create a symbol table entry for the f
unction itself.  Furthermore, we need*/
			/* to have the function scoped one level above, which is
 why we call the current_symbol_table.parent.*/
			/* Finally, though, we want the function to be callable 
from in itself, so we need to add it*/
			/* to the symbol table before we process the compound_st
atement.  Otherwise, we wouldn't*/
			/* be able to do recursion.*/
    	}
break;
case 103:
//#line 1466 "upbeat-a.yacc"
{
	    	/* First, check if variable is declared already; if not, add to 
symbol table*/
			if(current_symbol_table.parent.GetFuncReturnType(val_pee
k(4).code) == null) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( upbeatVal.Type.ubVOID );
				fType.SetArgs( val_peek(1).listTypes );
				current_symbol_table.parent.AddFuncSymbol( val_p
eek(4).code, fType, lexer.current_line());
			} else {
				yyerror("Function " + val_peek(4).sval + " alrea
dy defined on line " +
						current_symbol_table.parent.GetF
uncDefLine(val_peek(4).code));
			}
	    }
break;
case 104:
//#line 1479 "upbeat-a.yacc"
{
    		String funcode = new String("\n");
    		yyval = new upbeatVal(upbeatVal.Type.ubVOID);
    		if(val_peek(6).sval.equals("Conduct")) {
    			funcode = funcode.concat("protected ");
    		}
    		funcode = funcode.concat("void " + val_peek(6).code + "(" + val_
peek(3).code + ") " + val_peek(0).code);
    		yyval.code = funcode;
        	current_symbol_table = current_symbol_table.parent;
    	}
break;
case 105:
//#line 1490 "upbeat-a.yacc"
{
	    	/* First, check if variable is declared already; if not, add to 
symbol table*/
			if(current_symbol_table.GetFuncReturnType(val_peek(2).co
de) == null) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( val_peek(3).type );
				current_symbol_table.AddFuncSymbol( val_peek(2).
code, fType, lexer.current_line());
			} else {
				yyerror("Function " + val_peek(2).sval + " alrea
dy defined on line " +
						current_symbol_table.parent.GetF
uncDefLine(val_peek(2).code));
			}
			
			/* We need a new symbol table to scope arguments to the 
function.*/
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = val_peek(2).code;
	    }
break;
case 106:
//#line 1508 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(5).type);
    		if(val_peek(4).sval.equals("Conduct")) {
    			yyerror("Conduct function should not have a return type"
);
    		}
    		yyval.code = "\n" + val_peek(5).code + " " + val_peek(4).code + 
"() " + val_peek(0).code;
    		if( !current_symbol_table.returns ) {
    			yyerror("Function " + val_peek(4).code + " does not retu
rn a value");
    		}
    		current_symbol_table = current_symbol_table.parent;
    	}
break;
case 107:
//#line 1520 "upbeat-a.yacc"
{
			/* We need a new symbol table to scope arguments to the 
function.*/
			SymbolTable t = new SymbolTable(current_symbol_table);
			current_symbol_table = t;
			current_symbol_table.inConductorFunc = true;
			current_symbol_table.myName = val_peek(1).code;
    	}
break;
case 108:
//#line 1528 "upbeat-a.yacc"
{
	    	/* First, check if variable is declared already; if not, add to 
symbol table */
			if(current_symbol_table.parent.GetFuncReturnType(val_pee
k(4).code) == null) {
				FunctionType fType = new FunctionType();
				fType.SetReturnType( val_peek(5).type );
				fType.SetArgs( val_peek(1).listTypes );
				current_symbol_table.parent.AddFuncSymbol( val_p
eek(4).code, fType, lexer.current_line());
			} else {
				yyerror("Function " + val_peek(4).code + " alrea
dy defined on line " +
						current_symbol_table.parent.GetF
uncDefLine(val_peek(4).code));
			}
	    }
break;
case 109:
//#line 1541 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(7).type);
    		if(val_peek(6).sval.equals("Conduct")) {
    			yyerror("Conduct function should not have a return type"
);
    		}
    		yyval.code = "\n" + val_peek(7).code + " " + val_peek(6).code + 
"(" + val_peek(3).code + ") " + val_peek(0).code;
    		if( !current_symbol_table.returns ) {
    			yyerror("Function " + val_peek(6).code + " does not retu
rn a value");
    		}
    		current_symbol_table = current_symbol_table.parent;
    	}
break;
case 110:
//#line 1557 "upbeat-a.yacc"
{
    	String newCode = new String("");
    	newCode = newCode.concat( "AddCueToScore( " );
    	newCode = newCode.concat( perform_cast( val_peek(2).type, upbeatVal.Type
.ubCUE ) );
    	newCode = newCode.concat( val_peek(2).code + ", " );
    	newCode = newCode.concat( perform_cast( val_peek(1).type, upbeatVal.Type
.ubTIME) );
    	newCode = newCode.concat(val_peek(1).code + ");\n");
    	
    	yyval = new upbeatVal(newCode);
    }
break;
case 111:
//#line 1570 "upbeat-a.yacc"
{ yyval = new upbeatVal( val_peek(1).code + ";\n" ); }
break;
case 112:
//#line 1571 "upbeat-a.yacc"
{ yyval = new upbeatVal( val_peek(1).code + ";\n" ); }
break;
case 113:
//#line 1576 "upbeat-a.yacc"
{
    		String newCode = new String("getMusicMaker().change");
    		switch (val_peek(2).changeParam ){
    		case Pitch:
    			newCode = newCode.concat("Pitch");
    			break;
    		case Volume:
    			newCode = newCode.concat("Volume");
    			break;
    		case Instrument:
    			newCode = newCode.concat("Instrument");
    			break;
    		}
    		
    		switch (val_peek(1).toOrBy ){
    		case To:
    			newCode = newCode.concat("To");
    			break;
    		case By:
    			newCode = newCode.concat("By");
    			break;
    		}
    		
    		newCode = newCode.concat("(");
    		newCode = newCode.concat( perform_cast( val_peek(0).type, upbeat
Val.Type.ubINT) );
    		newCode = newCode.concat(val_peek(0).code);
    		newCode = newCode.concat(", ");
    		if(current_symbol_table.inCueResponse) {
    			newCode = newCode.concat("cue.getTime()");
    		} else {
    			newCode = newCode.concat("1");
    		}
    		newCode = newCode.concat(")");
    		yyval = new upbeatVal(newCode);
    	}
break;
case 114:
//#line 1614 "upbeat-a.yacc"
{ yyval = new upbeatVal( upbeatVal.ChangeParam.Volume ); }
break;
case 115:
//#line 1615 "upbeat-a.yacc"
{ yyval = new upbeatVal( upbeatVal.ChangeParam.Instrument ); }
break;
case 116:
//#line 1616 "upbeat-a.yacc"
{ yyval = new upbeatVal( upbeatVal.ChangeParam.Pitch ); }
break;
case 117:
//#line 1620 "upbeat-a.yacc"
{ yyval = new upbeatVal( upbeatVal.ToBy.To ); }
break;
case 118:
//#line 1621 "upbeat-a.yacc"
{ yyval = new upbeatVal( upbeatVal.ToBy.By ); }
break;
case 119:
//#line 1626 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat(val_peek(1).code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
val_peek(1).sval));
    	
    	if (val_peek(0) != null) {
    		code = code.concat(val_peek(0).code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, val_peek(0).sval));    		
    	}
    	
    	
    	code = code.concat(String.format("getMusicMaker().appendPhraseAt(%s, cue
.getTime())", tempVarName));
    	yyval = new upbeatVal(code);
    }
break;
case 122:
//#line 1651 "upbeat-a.yacc"
{
    		String code = new String();
    		String tempVarName = getNextTempName();
        	code = code.concat(String.format("MusicPhrase %s = new MusicPhra
se();\n", tempVarName));
        	for (String p : val_peek(1).listval) {
        		code = code.concat(String.format("%s.appendPhrase(%s);\n
", tempVarName, p));
        	}
    		code = code.concat(String.format("%s.setRepeat(-1);\n", tempVarN
ame));
    		upbeatVal res = new upbeatVal(code);
    		res.sval = tempVarName;
    		yyval = res;
    	}
break;
case 123:
//#line 1664 "upbeat-a.yacc"
{
	    	String code = new String();
			String tempVarName = getNextTempName();
	    	code = code.concat(String.format("MusicPhrase %s = new MusicPhra
se();\n", tempVarName));
	    	for (String p : val_peek(2).listval) {
	    		code = code.concat(String.format("%s.appendPhrase(%s);\n
", tempVarName, p));
	    	}
			code = code.concat(String.format("%s.setRepeat(%s);\n", 
tempVarName, val_peek(0).code));
			upbeatVal res = new upbeatVal(code);
			res.sval = tempVarName;
			yyval = res;
    	}
break;
case 124:
//#line 1680 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : val_peek(1).listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		yyval = res;
    }
break;
case 125:
//#line 1695 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat(val_peek(1).code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
val_peek(1).sval));
    	
    	if (val_peek(0) != null) {
    		code = code.concat(val_peek(0).code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, val_peek(0).sval));    		
    	}
    	
    	yyval = new upbeatVal(code);
    	yyval.sval = tempVarName;
    }
break;
case 126:
//#line 1711 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	code = code.concat(val_peek(1).code);
    	code = code.concat(String.format("%s.appendPhrase(%s);\n", tempVarName, 
val_peek(1).sval));
    	
    	if (val_peek(0) != null) {
    		code = code.concat(val_peek(0).code);
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, val_peek(0).sval));    		
    	}
    	
    	yyval = new upbeatVal(code);
    	yyval.sval = tempVarName;
    }
break;
case 127:
//#line 1727 "upbeat-a.yacc"
{
    		yyval = null;
    	}
break;
case 128:
//#line 1734 "upbeat-a.yacc"
{
    		if(current_symbol_table.GetType(val_peek(0).sval) == null) {
    			yyerror("Using " + val_peek(0).sval + " without having d
eclared it");
    		}
    		yyval = new upbeatVal("");
    		yyval.sval = val_peek(0).sval;
    		yyval.type = current_symbol_table.GetType(val_peek(0).sval);
    		if (yyval.type != upbeatVal.Type.ubPHRASE) {
    			yyerror ("Using a non-phrase variable in the musical phr
ase play statement is not allowed");
    		}
    		yyval.listval = new LinkedList<String>();
    		yyval.listval.add(val_peek(0).code);
		}
break;
case 129:
//#line 1748 "upbeat-a.yacc"
{
			if(current_symbol_table.GetType(val_peek(2).sval) == nul
l) {
				yyerror("Using " + val_peek(2).sval + " without 
having declared it");
			}
			if( current_symbol_table.GetType(val_peek(2).sval) != up
beatVal.Type.ubPHRASE ) {
				yyerror("Using a non-phrase variable in a musica
l phrase play statement is not allowed");
			}
			yyval = new upbeatVal("");
			yyval.sval = val_peek(2).sval;
    		yyval.type = upbeatVal.Type.ubPHRASE;
			yyval.listval = new LinkedList<String>();
			yyval.listval.add(val_peek(2).code);
			if(val_peek(0).listval != null) {
				for(String p : val_peek(0).listval) {
					yyval.listval.add(p);
				}
			}
    	}
break;
case 130:
//#line 1767 "upbeat-a.yacc"
{
    	/*NOTE: ALL constants of type "ubPHRASE" are RESTS.*/
    	if(val_peek(0).type != upbeatVal.Type.ubPHRASE) {
    		yyerror ("Musical phrases can only contain variables of type " +
 upbeatTypeName(upbeatVal.Type.ubPHRASE) + " or RESTs");
    	}
    	yyval = new upbeatVal("");
    	yyval.listval = new LinkedList<String>();
    	yyval.listval.add("MusicPhrase.getREST()");
    }
break;
case 131:
//#line 1777 "upbeat-a.yacc"
{
    	/*NOTE: ALL constants of type "ubPHRASE" are RESTS.*/
    	if(val_peek(2).type != upbeatVal.Type.ubPHRASE) {
    		yyerror ("Musical phrases can only contain variables of type " +
 upbeatTypeName(upbeatVal.Type.ubPHRASE) + " or RESTs");
    	}
    	yyval = new upbeatVal("");
    	yyval.listval = new LinkedList<String>();
    	yyval.listval.add("MusicPhrase.getREST()");
    	
    	if(val_peek(0).listval != null) {
			for(String p : val_peek(0).listval) {
				yyval.listval.add(p);
			}
		}
    }
break;
case 132:
//#line 1796 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : val_peek(1).listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		code = code.concat(String.format("%s.setRepeat(-1);\n", tempVarN
ame));
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		yyval = res;
    }
break;
case 133:
//#line 1809 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	
    	for (String p : val_peek(2).listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		code = code.concat(String.format("%s.setRepeat(%s);\n", tempVarN
ame, val_peek(0).code));
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		yyval = res;
    }
break;
case 134:
//#line 1826 "upbeat-a.yacc"
{
    	String code = new String();
		String tempVarName = getNextTempName();
    	code = code.concat(String.format("MusicPhrase %s = new MusicPhrase();\n"
, tempVarName));
    	for (String p : val_peek(1).listval) {
    		code = code.concat(String.format("%s.appendPhrase(%s);\n", tempV
arName, p));
    	}
		upbeatVal res = new upbeatVal(code);
		res.sval = tempVarName;
		yyval = res;
    }
break;
case 135:
//#line 1842 "upbeat-a.yacc"
{
			Hashtable<String, String> musician_code = new Hashtable<
String, String>();
			musician_code.put(val_peek(0).sval, val_peek(0).code);
    		yyval = new upbeatVal(1);
    		/* TODO: clean up the way we assign musician code*/
    		yyval.obj = musician_code;
    		/* ival indicates number of musicians*/
    	}
break;
case 136:
//#line 1851 "upbeat-a.yacc"
{
			Hashtable<String, String> musician_code = new Hashtable<
String, String>();
			Hashtable<String, String> orig;
			Enumeration<String> k;
    		/* TODO: clean up the way we assign musician code*/
			orig = (Hashtable)val_peek(1).obj;
			k = orig.keys();
			while(k != null && k.hasMoreElements()) {
				String key = k.nextElement();
				if (key.equals(val_peek(0).sval)) {
					yyerror ("can't have more than one music
ian with the same name");
				}
				musician_code.put(key, orig.get(key));
			}
			/* TODO: clean up the way we assign musician code*/
			musician_code.put(val_peek(0).sval, val_peek(0).code);
			yyval = new upbeatVal(1 + val_peek(1).ival);
			/* TODO: clean up the way we assign musician code*/
			yyval.obj = musician_code;
			/* ival indicates number of musicians*/
    	}
break;
case 137:
//#line 1876 "upbeat-a.yacc"
{
    		SymbolTable t = new SymbolTable(current_symbol_table);
    		current_symbol_table = t;
    	}
break;
case 138:
//#line 1881 "upbeat-a.yacc"
{
    		String gen_code = new String();
    		
    		gen_code = gen_code.concat("package upbeat.sample;\n\n" +
    				"import upbeat.Musician;\n" +
    				"import upbeat.types.Cue;\n" +
    				"import upbeat.types.MusicPhrase;\n" +
    				"\n" +
    				"public class Musician_" + val_peek(4).code + " 
extends Musician {\n");
    		
    		if(val_peek(1).listval != null) {
    			for(String decl : val_peek(1).listval) {
    				gen_code = gen_code.concat(decl + "\n");
    			}
    		}
    		
    		try {
    		gen_code = gen_code.concat("	public Musician_" + val_peek(4).
code + "() {\n" +
    				" 		// Call the Parent constructor.\
n" +
    				"		super(" + getNextMusicianChannel
() + ");\n" +
    				"		" + 
    				"		// Initializations.\n" +
    				val_peek(1).sval +
    				"	}\n" +
    				val_peek(1).code +
    				"\n}\n");
    		} catch (Error e) {
    			yyerror("Error creating next musician: " + e.getMessage(
));
    		}
    		yyval = new upbeatVal(gen_code);
    		yyval.sval = val_peek(4).code; /* code has name of musician*/
        	current_symbol_table = current_symbol_table.parent;
    	}
break;
case 139:
//#line 1918 "upbeat-a.yacc"
{
    		String newCode = new String();
    		
	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( val_peek(0).code );
	    	newCode = newCode.concat( "\n}" );
	    	
	    	yyval = new upbeatVal( newCode );
	    	yyval.sval = val_peek(1).code; /* statements*/
	    	yyval.listval = null; /* no declarations*/
    	}
break;
case 140:
//#line 1930 "upbeat-a.yacc"
{
	    	String newCode = new String();
	    	
	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( val_peek(0).code );
	    	newCode = newCode.concat( "\n}" );
	    	
	    	yyval = new upbeatVal( newCode );
	    	yyval.sval = ""; /* no statements*/
	    	yyval.listval = new LinkedList<String>();
    		yyval.listval.add(val_peek(1).code);
	    }
break;
case 141:
//#line 1943 "upbeat-a.yacc"
{
	    	String newCode = new String();
	    	
/* A little hacky, but for musicians:
 * 1. The code field contains the entire processCue method.
 * 2. The sval field contains statements which go in the constructor
 * 3. The listval probably only contains one element which is the declarations; 
these go at the top of the class
 */

	    	newCode = newCode.concat( "\n\n@Override\npublic void processCue
(Cue cue) throws Exception {\n" );
	    	newCode = newCode.concat( val_peek(0).code );
    		newCode = newCode.concat( "\n}" );
	    	
	    	yyval = new upbeatVal( newCode );
	    	yyval.sval = val_peek(1).code;
	    	yyval.listval = new LinkedList<String>();
    		yyval.listval.add(val_peek(2).code);
	    }
break;
case 142:
//#line 1965 "upbeat-a.yacc"
{
    		yyval = new upbeatVal(val_peek(0).code);
    	}
break;
case 143:
//#line 1969 "upbeat-a.yacc"
{
    		String newCode = new String(val_peek(1).code + "\n" + val_peek(0
).code + "\n");
    		yyval = new upbeatVal( newCode );
    	}
break;
case 144:
//#line 1977 "upbeat-a.yacc"
{
	    	SymbolTable t = new SymbolTable(current_symbol_table);
	    	current_symbol_table = t;
	    	current_symbol_table.inCueResponse = true;
	    }
break;
case 145:
//#line 1983 "upbeat-a.yacc"
{
    		String newCode = new String("if (cue.getName().equals(" + val_pe
ek(2).sval + ") )\n" + val_peek(0).code + "\n");
    		yyval = new upbeatVal( newCode );
    		
    		current_symbol_table = current_symbol_table.parent;
    	}
break;
//#line 3466 "parser.java"
//########## END OF USER-SUPPLIED ACTIONS ##########
    }//switch
    //#### Now let's reduce... ####
    if (yydebug) debug("reduce");
    state_drop(yym);             //we just reduced yylen states
    yystate = state_peek(0);     //get new state
    val_drop(yym);               //corresponding value drop
    yym = yylhs[yyn];            //select next TERMINAL(on lhs)
    if (yystate == 0 && yym == 0)//done? 'rest' state and at first TERMINAL
      {
      if (yydebug) debug("After reduction, shifting from state 0 to state "+YYFI
NAL+"");
      yystate = YYFINAL;         //explicitly say we're done
      state_push(YYFINAL);       //and save it
      val_push(yyval);           //also save the semantic value of parsing
      if (yychar < 0)            //we want another character?
        {
        yychar = yylex();        //get next character
        if (yychar<0) yychar=0;  //clean, if necessary
        if (yydebug)
          yylexdebug(yystate,yychar);
        }
      if (yychar == 0)          //Good exit (if lex returns 0 ;-)
         break;                 //quit the loop--all DONE
      }//if yystate
    else                        //else not done yet
      {                         //get next state and push, for next yydefred[]
      yyn = yygindex[yym];      //find out where to go
      if ((yyn != 0) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
        yystate = yytable[yyn]; //get new state
      else
        yystate = yydgoto[yym]; //else go to new defred
      if (yydebug) debug("after reduction, shifting from state "+state_peek(0)+"
 to state "+yystate+"");
      state_push(yystate);     //going again, so push state & val...
      val_push(yyval);         //for next action
      }
    }//main loop
  return 0;//yyaccept!!
}
//## end of method parse() ######################################



//## run() --- for Thread #######################################
/**
 * A default run method, used for operating this parser
 * object in the background.  It is intended for extending Thread
 * or implementing Runnable.  Turn off with -Jnorun .
 */
public void run()
{
  yyparse();
}
//## end of method run() ########################################



//## Constructors ###############################################
//## The -Jnoconstruct option was used ##
//###############################################################



}
//################### END OF CLASS ##############################




Filename: Frontend//src/upbeat/frontend/Yylex.java
Author: Team
/* The following code was generated by JFlex 1.4.3 on 5/6/10 9:41 PM */

package upbeat.frontend;

/**
 * This class is a scanner generated by 
 * <a href="http://www.jflex.de/">JFlex</a> 1.4.3
 * on 5/6/10 9:41 PM from the specification file
 * <tt>C:/Documents and Settings/sherwood.DESHAW/upbeat/code/upbeat/Frontend/lex
er_parser_src/upbeat.flex</tt>
 */
class Yylex {

  /** This character denotes the end of file */
  public static final int YYEOF = -1;

  /** initial size of the lookahead buffer */
  private static final int ZZ_BUFFERSIZE = 16384;

  /** lexical states */
  public static final int YYINITIAL = 0;

  /**
   * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
   * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l
   *                  at the beginning of a line
   * l is of the form l = 2*k, k a non negative integer
   */
  private static final int ZZ_LEXSTATE[] = { 
     0, 0
  };

  /** 
   * Translates characters to character classes
   */
  private static final String ZZ_CMAP_PACKED = 
    "\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\26\1\35\1\24"+
    "\1\0\1\10\1\30\2\0\1\30\1\30\1\7\1\30\1\30\1\34"+
    "\1\11\1\6\12\5\1\32\1\27\1\36\1\31\1\37\1\0\1\22"+
    "\1\17\1\4\1\55\1\4\1\15\1\16\1\51\1\4\1\46\2\4"+
    "\1\20\1\47\1\52\1\54\1\53\1\4\1\13\1\21\1\12\1\14"+
    "\1\64\4\4\1\30\1\25\1\30\1\0\1\50\1\0\1\40\1\70"+
    "\1\57\1\42\1\62\1\67\1\72\1\71\1\45\2\4\1\65\1\23"+
    "\1\41\1\43\1\63\1\4\1\44\1\61\1\60\1\56\1\66\2\4"+
    "\1\73\1\4\1\30\1\33\1\30\1\25\uff81\0";

  /** 
   * Translates characters to character classes
   */
  private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED);

  /** 
   * Translates DFA states to action switch labels.
   */
  private static final int [] ZZ_ACTION = zzUnpackAction();

  private static final String ZZ_ACTION_PACKED_0 =
    "\1\0\1\1\1\2\1\3\1\4\2\5\1\6\4\3"+
    "\1\1\1\3\1\1\1\7\1\10\3\5\1\11\1\12"+
    "\17\3\3\0\7\3\1\0\1\3\1\0\1\13\1\14"+
    "\1\0\1\15\1\16\1\17\1\20\2\3\1\21\1\22"+
    "\7\3\1\23\6\3\1\24\1\25\2\26\1\0\7\3"+
    "\1\27\1\30\1\3\1\31\1\32\1\3\1\33\10\3"+
    "\1\34\6\3\1\35\2\3\1\36\2\3\1\37\1\40"+
    "\4\3\1\41\3\3\1\42\4\3\1\43\1\44\1\0"+
    "\2\3\1\45\2\3\1\46\6\3\1\47\1\0\1\50"+
    "\1\51\3\3\1\52\1\3\1\53\1\54\1\3\1\0"+
    "\4\3\1\55\1\0\1\3\1\56\2\3\1\0\1\3"+
    "\1\57\1\3\1\0\1\60\1\3\1\0\1\3\1\0"+
    "\1\61\1\0\1\62";

  private static int [] zzUnpackAction() {
    int [] result = new int[181];
    int offset = 0;
    offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
    return result;
  }

  private static int zzUnpackAction(String packed, int offset, int [] result) {
    int i = 0;       /* index in packed string  */
    int j = offset;  /* index in unpacked array */
    int l = packed.length();
    while (i < l) {
      int count = packed.charAt(i++);
      int value = packed.charAt(i++);
      do result[j++] = value; while (--count > 0);
    }
    return j;
  }


  /** 
   * Translates a state to a row index in the transition table
   */
  private static final int [] ZZ_ROWMAP = zzUnpackRowMap();

  private static final String ZZ_ROWMAP_PACKED_0 =
    "\0\0\0\74\0\170\0\264\0\360\0\u012c\0\74\0\74"+
    "\0\u0168\0\u01a4\0\u01e0\0\u021c\0\u0258\0\u0294\0\u02d0\0\74"+
    "\0\u030c\0\u0348\0\u0384\0\u03c0\0\u03fc\0\u0438\0\u0474\0\u04b0"+
    "\0\u04ec\0\u0528\0\u0564\0\u05a0\0\u05dc\0\u0618\0\u0654\0\u0690"+
    "\0\u06cc\0\u0708\0\u0744\0\u0780\0\u07bc\0\u07f8\0\u0834\0\u0870"+
    "\0\u08ac\0\u08e8\0\u0924\0\u0960\0\u099c\0\u09d8\0\u0a14\0\u0a50"+
    "\0\u0a8c\0\u02d0\0\74\0\74\0\u0ac8\0\74\0\74\0\74"+
    "\0\74\0\u0b04\0\u0b40\0\264\0\u0b7c\0\u0bb8\0\u0bf4\0\u0c30"+
    "\0\u0c6c\0\u0ca8\0\u0ce4\0\u0d20\0\264\0\u0d5c\0\u0d98\0\u0dd4"+
    "\0\u0e10\0\u0e4c\0\u0e88\0\264\0\u07f8\0\u0ec4\0\74\0\u0f00"+
    "\0\u0f3c\0\u0f78\0\u0fb4\0\u0ff0\0\u102c\0\u1068\0\u10a4\0\264"+
    "\0\u0a50\0\u10e0\0\74\0\264\0\u111c\0\264\0\u1158\0\u1194"+
    "\0\u11d0\0\u120c\0\u1248\0\u1284\0\u12c0\0\u12fc\0\264\0\u1338"+
    "\0\u1374\0\u13b0\0\u13ec\0\u1428\0\u1464\0\264\0\u14a0\0\u14dc"+
    "\0\264\0\u1518\0\u1554\0\264\0\264\0\u1590\0\u15cc\0\u1608"+
    "\0\u1644\0\264\0\u1680\0\u16bc\0\u16f8\0\264\0\u1734\0\u1770"+
    "\0\u17ac\0\u17e8\0\264\0\264\0\u1824\0\u1860\0\u189c\0\264"+
    "\0\u18d8\0\u1914\0\264\0\u1950\0\u198c\0\u19c8\0\u1a04\0\u1a40"+
    "\0\u1a7c\0\264\0\u1ab8\0\264\0\264\0\u1af4\0\u1b30\0\u1b6c"+
    "\0\264\0\u1ba8\0\264\0\264\0\u1be4\0\u1c20\0\u1c5c\0\u1c98"+
    "\0\u1cd4\0\u1d10\0\264\0\u1d4c\0\u1d88\0\264\0\u1dc4\0\u1e00"+
    "\0\u1e3c\0\u1e78\0\264\0\u1eb4\0\u1ef0\0\264\0\u1f2c\0\u1f68"+
    "\0\u1fa4\0\u1fe0\0\264\0\u201c\0\74";

  private static int [] zzUnpackRowMap() {
    int [] result = new int[181];
    int offset = 0;
    offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
    return result;
  }

  private static int zzUnpackRowMap(String packed, int offset, int [] result) {
    int i = 0;  /* index in packed string  */
    int j = offset;  /* index in unpacked array */
    int l = packed.length();
    while (i < l) {
      int high = packed.charAt(i++) << 16;
      result[j++] = high | packed.charAt(i++);
    }
    return j;
  }

  /** 
   * The transition table of the DFA
   */
  private static final int [] ZZ_TRANS = zzUnpackTrans();

  private static final String ZZ_TRANS_PACKED_0 =
    "\1\2\3\3\1\4\1\5\1\6\1\7\1\10\1\7"+
    "\1\11\1\12\2\4\1\13\1\14\2\4\1\15\1\16"+
    "\1\17\1\2\1\3\1\20\1\7\1\21\1\22\1\23"+
    "\1\7\1\24\1\25\1\26\1\27\1\4\1\30\1\31"+
    "\1\4\1\32\1\33\1\34\1\2\2\4\1\35\1\4"+
    "\1\36\1\4\1\37\1\40\2\4\1\41\1\42\1\4"+
    "\1\43\1\44\1\45\3\4\75\0\3\3\22\0\1\3"+
    "\51\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\23\4\5\0\1\5\3\0\1\46\70\0\1\47"+
    "\1\50\70\0\2\4\4\0\1\4\1\51\1\4\1\52"+
    "\4\4\1\0\1\4\14\0\6\4\1\53\1\4\1\0"+
    "\23\4\4\0\2\4\4\0\3\4\1\54\4\4\1\0"+
    "\1\4\14\0\10\4\1\0\11\4\1\55\11\4\4\0"+
    "\2\4\4\0\5\4\1\56\2\4\1\0\1\4\14\0"+
    "\10\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\2\4\1\57\5\4\1\0\23\4\23\0"+
    "\1\60\54\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\3\4\1\61\4\4\1\0\23\4\4\0\3\62\2\0"+
    "\11\62\1\0\1\62\1\63\2\62\5\0\1\62\3\0"+
    "\34\62\31\0\1\64\75\0\1\65\73\0\1\66\71\0"+
    "\1\67\73\0\1\70\73\0\1\71\46\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\1\4\1\72\6\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\1\73\7\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\4\4\1\74\3\4\1\0\23\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\1\4"+
    "\1\75\6\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\1\4\1\76\6\4\1\0\23\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\5\4\1\77\15\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\5\4\1\100\2\4\1\0\23\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\1\101"+
    "\2\4\1\102\4\4\1\0\20\4\1\103\2\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\10\4\1\0"+
    "\5\4\1\104\15\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\3\4\1\105\1\4\1\106\2\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\10\4\1\0\20\4\1\107\2\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\3\4\1\110\4\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\1\111\7\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\14\4\1\112\6\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\3\4"+
    "\1\113\4\4\1\0\22\4\1\114\5\0\1\115\66\0"+
    "\1\47\1\116\1\117\71\47\7\50\1\120\64\50\4\0"+
    "\2\4\4\0\2\4\1\121\5\4\1\0\1\4\14\0"+
    "\10\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\7\4\1\122\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\7\4\1\123\1\0"+
    "\23\4\4\0\2\4\4\0\7\4\1\124\1\0\1\4"+
    "\14\0\10\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\7\4\1\125\2\4"+
    "\1\126\10\4\4\0\2\4\4\0\6\4\1\127\1\4"+
    "\1\0\1\4\14\0\10\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\2\4\1\130\5\4"+
    "\1\0\23\4\5\0\1\131\72\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\4\4\1\132\3\4\1\0\23\4"+
    "\33\0\1\133\44\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\2\4\1\134\5\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\7\4"+
    "\1\135\13\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\7\4\1\136\2\4\1\137\10\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\10\4\1\140\12\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\10\4\1\141\12\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\7\4\1\142\13\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\10\4\1\143\12\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\1\4"+
    "\1\144\6\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\1\145\7\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\4\4\1\146"+
    "\3\4\1\0\11\4\1\147\11\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\150\14\0\10\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\4\4\1\151"+
    "\3\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\10\4\1\0\14\4\1\152\6\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\10\4\1\0"+
    "\14\4\1\153\6\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\3\4\1\154\4\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\3\4\1\155"+
    "\4\4\1\0\23\4\2\0\1\117\71\0\6\50\1\117"+
    "\1\120\64\50\4\0\2\4\4\0\3\4\1\156\4\4"+
    "\1\0\1\4\14\0\10\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\2\4"+
    "\1\157\20\4\4\0\2\4\4\0\3\4\1\160\4\4"+
    "\1\0\1\4\14\0\10\4\1\0\23\4\4\0\2\4"+
    "\4\0\1\161\7\4\1\0\1\4\14\0\10\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\10\4\1\0\5\4\1\162\15\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\10\4\1\0\11\4\1\163"+
    "\11\4\4\0\2\4\4\0\7\4\1\121\1\0\1\4"+
    "\14\0\10\4\1\0\23\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\11\4\1\164\11\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\1\165"+
    "\7\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\10\4\1\0\5\4\1\166\15\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\10\4\1\0"+
    "\7\4\1\167\13\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\5\4\1\170\2\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\10\4\1\0"+
    "\6\4\1\171\14\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\10\4\1\0\11\4\1\172\11\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\2\4\1\173"+
    "\5\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\1\4\1\174\6\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\4\4\1\175"+
    "\3\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\10\4\1\0\11\4\1\176\11\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\1\177\7\4"+
    "\1\0\23\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\5\4\1\200\15\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\5\4"+
    "\1\201\15\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\1\202\7\4\1\0\23\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\10\4\1\0\14\4\1\203"+
    "\6\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\10\4\1\0\3\4\1\204\17\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\10\4\1\205\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\4\4\1\206"+
    "\3\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\1\207\7\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\7\4"+
    "\1\210\13\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\4\4\1\211\3\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\6\4"+
    "\1\212\14\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\20\4\1\213\2\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\5\4"+
    "\1\214\15\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\21\4\1\215\1\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\11\4"+
    "\1\216\11\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\10\4\1\217\12\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\220\14\0\10\4\1\0\23\4"+
    "\4\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\11\4\1\221\11\4\4\0\2\4\4\0\10\4"+
    "\1\0\1\4\14\0\10\4\1\0\7\4\1\222\13\4"+
    "\21\0\1\223\56\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\1\4\1\224\6\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\7\4"+
    "\1\225\13\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\5\4\1\226\15\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\5\4\1\227\2\4"+
    "\1\0\23\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\6\4\1\230\14\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\11\4"+
    "\1\231\11\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\1\4\1\232\6\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\11\4"+
    "\1\233\11\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\11\4\1\234\11\4\4\0\2\4"+
    "\4\0\5\4\1\235\2\4\1\0\1\4\14\0\10\4"+
    "\1\0\23\4\46\0\1\236\31\0\2\4\4\0\10\4"+
    "\1\0\1\237\14\0\10\4\1\0\23\4\4\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\1\240\7\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\10\4\1\0\7\4\1\241\13\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\10\4\1\0\7\4\1\242"+
    "\13\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\10\4\1\0\7\4\1\243\13\4\51\0\1\244\26\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\10\4\1\0"+
    "\11\4\1\245\11\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\1\4\1\246\6\4\1\0\23\4\4\0"+
    "\2\4\4\0\10\4\1\0\1\4\14\0\3\4\1\247"+
    "\4\4\1\0\23\4\4\0\2\4\4\0\10\4\1\0"+
    "\1\4\14\0\10\4\1\0\13\4\1\250\7\4\52\0"+
    "\1\251\25\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\1\4\1\252\6\4\1\0\23\4\4\0\2\4\4\0"+
    "\10\4\1\0\1\4\14\0\4\4\1\253\3\4\1\0"+
    "\23\4\4\0\2\4\4\0\10\4\1\0\1\4\14\0"+
    "\1\254\7\4\1\0\23\4\17\0\1\255\60\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\7\4"+
    "\1\256\13\4\4\0\2\4\4\0\10\4\1\0\1\4"+
    "\14\0\10\4\1\0\14\4\1\257\6\4\12\0\1\260"+
    "\65\0\2\4\4\0\10\4\1\0\1\4\14\0\10\4"+
    "\1\0\5\4\1\261\15\4\14\0\1\262\63\0\2\4"+
    "\4\0\10\4\1\0\1\4\14\0\10\4\1\0\11\4"+
    "\1\263\11\4\13\0\1\264\75\0\1\265\56\0";

  private static int [] zzUnpackTrans() {
    int [] result = new int[8280];
    int offset = 0;
    offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
    return result;
  }

  private static int zzUnpackTrans(String packed, int offset, int [] result) {
    int i = 0;       /* index in packed string  */
    int j = offset;  /* index in unpacked array */
    int l = packed.length();
    while (i < l) {
      int count = packed.charAt(i++);
      int value = packed.charAt(i++);
      value--;
      do result[j++] = value; while (--count > 0);
    }
    return j;
  }


  /* error codes */
  private static final int ZZ_UNKNOWN_ERROR = 0;
  private static final int ZZ_NO_MATCH = 1;
  private static final int ZZ_PUSHBACK_2BIG = 2;

  /* error messages for the codes above */
  private static final String ZZ_ERROR_MSG[] = {
    "Unkown internal scanner error",
    "Error: could not match input",
    "Error: pushback value was too large"
  };

  /**
   * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code>
   */
  private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();

  private static final String ZZ_ATTRIBUTE_PACKED_0 =
    "\1\0\1\11\4\1\2\11\7\1\1\11\25\1\3\0"+
    "\7\1\1\0\1\1\1\0\2\11\1\0\4\11\25\1"+
    "\1\11\1\0\12\1\1\11\51\1\1\0\15\1\1\0"+
    "\12\1\1\0\5\1\1\0\4\1\1\0\3\1\1\0"+
    "\2\1\1\0\1\1\1\0\1\1\1\0\1\11";

  private static int [] zzUnpackAttribute() {
    int [] result = new int[181];
    int offset = 0;
    offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
    return result;
  }

  private static int zzUnpackAttribute(String packed, int offset, int [] result)
 {
    int i = 0;       /* index in packed string  */
    int j = offset;  /* index in unpacked array */
    int l = packed.length();
    while (i < l) {
      int count = packed.charAt(i++);
      int value = packed.charAt(i++);
      do result[j++] = value; while (--count > 0);
    }
    return j;
  }

  /** the input device */
  private java.io.Reader zzReader;

  /** the current state of the DFA */
  private int zzState;

  /** the current lexical state */
  private int zzLexicalState = YYINITIAL;

  /** this buffer contains the current text to be matched and is
      the source of the yytext() string */
  private char zzBuffer[] = new char[ZZ_BUFFERSIZE];

  /** the textposition at the last accepting state */
  private int zzMarkedPos;

  /** the current text position in the buffer */
  private int zzCurrentPos;

  /** startRead marks the beginning of the yytext() string in the buffer */
  private int zzStartRead;

  /** endRead marks the last character in the buffer, that has been read
      from input */
  private int zzEndRead;

  /** number of newlines encountered up to the start of the matched text */
  private int yyline;

  /** the number of characters up to the start of the matched text */
  private int yychar;

  /**
   * the number of characters from the last newline up to the start of the 
   * matched text
   */
  private int yycolumn;

  /** 
   * zzAtBOL == true <=> the scanner is currently at the beginning of a line
   */
  private boolean zzAtBOL = true;

  /** zzAtEOF == true <=> the scanner is at the EOF */
  private boolean zzAtEOF;

  /** denotes if the user-EOF-code has already been executed */
  private boolean zzEOFDone;

  /* user code: */
  /* store a reference to the parser object */
  private parser yyparser;

  /* constructor taking an additional parser object */
  public Yylex(java.io.Reader r, parser yyparser) {
    this(r);
    this.yyparser = yyparser;
  }
  
  /* Useful debugging function */
  public String lexer_loc() {
	  return "line " + (yyline+1) + " col " + (yycolumn+1);
  }
  
  public int current_line() {
	  // for some reason, lines are 0-indexed!
	  return yyline+1;
  }
  
  private String bad_code(int fromhere) {
	  return new String( zzBuffer, zzStartRead, fromhere-zzStartRead );
  }


  /**
   * Creates a new scanner
   * There is also a java.io.InputStream version of this constructor.
   *
   * @param   in  the java.io.Reader to read input from.
   */
  Yylex(java.io.Reader in) {
    this.zzReader = in;
  }

  /**
   * Creates a new scanner.
   * There is also java.io.Reader version of this constructor.
   *
   * @param   in  the java.io.Inputstream to read input from.
   */
  Yylex(java.io.InputStream in) {
    this(new java.io.InputStreamReader(in));
  }

  /** 
   * Unpacks the compressed character translation table.
   *
   * @param packed   the packed character translation table
   * @return         the unpacked character translation table
   */
  private static char [] zzUnpackCMap(String packed) {
    char [] map = new char[0x10000];
    int i = 0;  /* index in packed string  */
    int j = 0;  /* index in unpacked array */
    while (i < 174) {
      int  count = packed.charAt(i++);
      char value = packed.charAt(i++);
      do map[j++] = value; while (--count > 0);
    }
    return map;
  }


  /**
   * Refills the input buffer.
   *
   * @return      <code>false</code>, iff there was new input.
   * 
   * @exception   java.io.IOException  if any I/O-Error occurs
   */
  private boolean zzRefill() throws java.io.IOException {

    /* first: make room (if you can) */
    if (zzStartRead > 0) {
      System.arraycopy(zzBuffer, zzStartRead,
                       zzBuffer, 0,
                       zzEndRead-zzStartRead);

      /* translate stored positions */
      zzEndRead-= zzStartRead;
      zzCurrentPos-= zzStartRead;
      zzMarkedPos-= zzStartRead;
      zzStartRead = 0;
    }

    /* is the buffer big enough? */
    if (zzCurrentPos >= zzBuffer.length) {
      /* if not: blow it up */
      char newBuffer[] = new char[zzCurrentPos*2];
      System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length);
      zzBuffer = newBuffer;
    }

    /* finally: fill the buffer with new input */
    int numRead = zzReader.read(zzBuffer, zzEndRead,
                                            zzBuffer.length-zzEndRead);

    if (numRead > 0) {
      zzEndRead+= numRead;
      return false;
    }
    // unlikely but not impossible: read 0 characters, but not at end of stream 
   
    if (numRead == 0) {
      int c = zzReader.read();
      if (c == -1) {
        return true;
      } else {
        zzBuffer[zzEndRead++] = (char) c;
        return false;
      }     
    }

	// numRead < 0
    return true;
  }

    
  /**
   * Closes the input stream.
   */
  public final void yyclose() throws java.io.IOException {
    zzAtEOF = true;            /* indicate end of file */
    zzEndRead = zzStartRead;  /* invalidate buffer    */

    if (zzReader != null)
      zzReader.close();
  }


  /**
   * Resets the scanner to read from a new input stream.
   * Does not close the old reader.
   *
   * All internal variables are reset, the old input stream 
   * <b>cannot</b> be reused (internal buffer is discarded and lost).
   * Lexical state is set to <tt>ZZ_INITIAL</tt>.
   *
   * @param reader   the new input stream 
   */
  public final void yyreset(java.io.Reader reader) {
    zzReader = reader;
    zzAtBOL  = true;
    zzAtEOF  = false;
    zzEOFDone = false;
    zzEndRead = zzStartRead = 0;
    zzCurrentPos = zzMarkedPos = 0;
    yyline = yychar = yycolumn = 0;
    zzLexicalState = YYINITIAL;
  }


  /**
   * Returns the current lexical state.
   */
  public final int yystate() {
    return zzLexicalState;
  }


  /**
   * Enters a new lexical state
   *
   * @param newState the new lexical state
   */
  public final void yybegin(int newState) {
    zzLexicalState = newState;
  }


  /**
   * Returns the text matched by the current regular expression.
   */
  public final String yytext() {
    return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead );
  }


  /**
   * Returns the character at position <tt>pos</tt> from the 
   * matched text. 
   * 
   * It is equivalent to yytext().charAt(pos), but faster
   *
   * @param pos the position of the character to fetch. 
   *            A value from 0 to yylength()-1.
   *
   * @return the character at position pos
   */
  public final char yycharat(int pos) {
    return zzBuffer[zzStartRead+pos];
  }


  /**
   * Returns the length of the matched text region.
   */
  public final int yylength() {
    return zzMarkedPos-zzStartRead;
  }


  /**
   * Reports an error that occured while scanning.
   *
   * In a wellformed scanner (no or only correct usage of 
   * yypushback(int) and a match-all fallback rule) this method 
   * will only be called with things that "Can't Possibly Happen".
   * If this method is called, something is seriously wrong
   * (e.g. a JFlex bug producing a faulty scanner etc.).
   *
   * Usual syntax/scanner level error handling should be done
   * in error fallback rules.
   *
   * @param   errorCode  the code of the errormessage to display
   */
  private void zzScanError(int errorCode) {
    String message;
    try {
      message = ZZ_ERROR_MSG[errorCode];
    }
    catch (ArrayIndexOutOfBoundsException e) {
      message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR];
    }

    throw new Error(message);
  } 


  /**
   * Pushes the specified amount of characters back into the input stream.
   *
   * They will be read again by then next call of the scanning method
   *
   * @param number  the number of characters to be read again.
   *                This number must not be greater than yylength()!
   */
  public void yypushback(int number)  {
    if ( number > yylength() )
      zzScanError(ZZ_PUSHBACK_2BIG);

    zzMarkedPos -= number;
  }


  /**
   * Contains user EOF-code, which will be executed exactly once,
   * when the end of file is reached
   */
  private void zzDoEOF() throws java.io.IOException {
    if (!zzEOFDone) {
      zzEOFDone = true;
      yyclose();
    }
  }


  /**
   * Resumes scanning until the next regular expression is matched,
   * the end of input is encountered or an I/O-Error occurs.
   *
   * @return      the next token
   * @exception   java.io.IOException  if any I/O-Error occurs
   */
  public int yylex() throws java.io.IOException {
    int zzInput;
    int zzAction;

    // cached fields:
    int zzCurrentPosL;
    int zzMarkedPosL;
    int zzEndReadL = zzEndRead;
    char [] zzBufferL = zzBuffer;
    char [] zzCMapL = ZZ_CMAP;

    int [] zzTransL = ZZ_TRANS;
    int [] zzRowMapL = ZZ_ROWMAP;
    int [] zzAttrL = ZZ_ATTRIBUTE;

    while (true) {
      zzMarkedPosL = zzMarkedPos;

      boolean zzR = false;
      for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL;
                                                             zzCurrentPosL++) {
        switch (zzBufferL[zzCurrentPosL]) {
        case '\u000B':
        case '\u000C':
        case '\u0085':
        case '\u2028':
        case '\u2029':
          yyline++;
          yycolumn = 0;
          zzR = false;
          break;
        case '\r':
          yyline++;
          yycolumn = 0;
          zzR = true;
          break;
        case '\n':
          if (zzR)
            zzR = false;
          else {
            yyline++;
            yycolumn = 0;
          }
          break;
        default:
          zzR = false;
          yycolumn++;
        }
      }

      if (zzR) {
        // peek one character ahead if it is \n (if we have counted one line too
 much)
        boolean zzPeek;
        if (zzMarkedPosL < zzEndReadL)
          zzPeek = zzBufferL[zzMarkedPosL] == '\n';
        else if (zzAtEOF)
          zzPeek = false;
        else {
          boolean eof = zzRefill();
          zzEndReadL = zzEndRead;
          zzMarkedPosL = zzMarkedPos;
          zzBufferL = zzBuffer;
          if (eof) 
            zzPeek = false;
          else 
            zzPeek = zzBufferL[zzMarkedPosL] == '\n';
        }
        if (zzPeek) yyline--;
      }
      zzAction = -1;

      zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL;
  
      zzState = ZZ_LEXSTATE[zzLexicalState];


      zzForAction: {
        while (true) {
    
          if (zzCurrentPosL < zzEndReadL)
            zzInput = zzBufferL[zzCurrentPosL++];
          else if (zzAtEOF) {
            zzInput = YYEOF;
            break zzForAction;
          }
          else {
            // store back cached positions
            zzCurrentPos  = zzCurrentPosL;
            zzMarkedPos   = zzMarkedPosL;
            boolean eof = zzRefill();
            // get translated positions and possibly new buffer
            zzCurrentPosL  = zzCurrentPos;
            zzMarkedPosL   = zzMarkedPos;
            zzBufferL      = zzBuffer;
            zzEndReadL     = zzEndRead;
            if (eof) {
              zzInput = YYEOF;
              break zzForAction;
            }
            else {
              zzInput = zzBufferL[zzCurrentPosL++];
            }
          }
          int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ];
          if (zzNext == -1) break zzForAction;
          zzState = zzNext;

          int zzAttributes = zzAttrL[zzState];
          if ( (zzAttributes & 1) == 1 ) {
            zzAction = zzState;
            zzMarkedPosL = zzCurrentPosL;
            if ( (zzAttributes & 8) == 8 ) break zzForAction;
          }

        }
      }

      // store back cached position
      zzMarkedPos = zzMarkedPosL;

      switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) {
        case 2: 
          { /* do nothing */
          }
        case 51: break;
        case 21: 
          { double thefloat = Double.parseDouble(yytext());
		  yyparser.yylval = new upbeatVal(thefloat);
		  yyparser.yylval.code = "" + thefloat;
		  yyparser.yylval.type = upbeatVal.Type.ubFLOAT;
			return parser.CONSTANT;
          }
        case 52: break;
        case 32: 
          { return parser.DATA;
          }
        case 53: break;
        case 49: 
          { return parser.CURRENT_VALUE;
          }
        case 54: break;
        case 27: 
          { return parser.INT;
          }
        case 55: break;
        case 43: 
          { return parser.PHRASE;
          }
        case 56: break;
        case 33: 
          { return parser.CASE;
          }
        case 57: break;
        case 16: 
          { return parser.GE_OP;
          }
        case 58: break;
        case 3: 
          { String idname = "";
	if(yytext().equals("Conduct") || yytext().equals("currentMeasure")) {
		idname = yytext();
	} else {
		idname = "ub_zz_" + yytext();
		// for scoping, namespace will be distinct
	}
	yyparser.yylval = new upbeatVal(idname);
			// creates a new upbeatVal where the Java code equivalen
t will be the variable name
			// in a special namespace.
		  yyparser.yylval.sval = yytext();
		    // Using sval to stand for the original variable name.
// TODO: Do we need a symbol table?
			return parser.IDENTIFIER;
          }
        case 59: break;
        case 23: 
          { return parser.ADD;
          }
        case 60: break;
        case 38: 
          { return parser.PITCH;
          }
        case 61: break;
        case 5: 
          { return yycharat(0);
          }
        case 62: break;
        case 45: 
          { return parser.VALUE_AT;
          }
        case 63: break;
        case 26: 
          { return parser.AND_OP;
          }
        case 64: break;
        case 46: 
          { return parser.MUSICIAN;
          }
        case 65: break;
        case 31: 
          { return parser.MORE;
          }
        case 66: break;
        case 44: 
          { return parser.VOLUME;
          }
        case 67: break;
        case 7: 
          { if (yyparser.yydebug) {
			System.out.print ("\n");
		  }
		  return yycharat(0); /* end of statement */
          }
        case 68: break;
        case 35: 
          { return parser.BOOL;
          }
        case 69: break;
        case 18: 
          { return parser.IN;
          }
        case 70: break;
        case 10: 
          { return parser.GREAT_OP;
          }
        case 71: break;
        case 40: 
          { return parser.RETURN;
          }
        case 72: break;
        case 39: 
          { return parser.FLOAT;
          }
        case 73: break;
        case 34: 
          { return parser.TIME;
          }
        case 74: break;
        case 25: 
          { return parser.RRPT;
          }
        case 75: break;
        case 42: 
          { return parser.CHANGE;
          }
        case 76: break;
        case 6: 
          { yyparser.yylval = new upbeatVal("cue");
	yyparser.yylval.type = upbeatVal.Type.ubCUE;
	yyparser.yylval.sval = "$";
	return parser.CURR_CUE;
          }
        case 77: break;
        case 8: 
          { return parser.EQ_ASS;
          }
        case 78: break;
        case 37: 
          { yyparser.yylval = new upbeatVal("input");
	return parser.INPUT;
          }
        case 79: break;
        case 20: 
          { return parser.BY;
          }
        case 80: break;
        case 1: 
          { throw new Error("Found something I shouldn't have: " + bad_code(zzCu
rrentPosL) + " at " + lexer_loc());
          }
        case 81: break;
        case 28: 
          { return parser.CUE;
          }
        case 82: break;
        case 29: 
          { if (yytext().equals("TRUE")) {
			yyparser.yylval = new upbeatVal(true);
			yyparser.yylval.code = "true";
		} else /* must be false */ {
			yyparser.yylval = new upbeatVal(false);
			yyparser.yylval.code = "false";
		}
			if (yyparser.yydebug) {
				System.out.printf("Ran across %s which is %s!\n"
, yytext(), yyparser.yylval.bval);
			}
			yyparser.yylval.type = upbeatVal.Type.ubBOOL;
			return parser.CONSTANT;
          }
        case 83: break;
        case 47: 
          { return parser.CONDUCTOR;
          }
        case 84: break;
        case 17: 
          { return parser.OR_OP;
          }
        case 85: break;
        case 15: 
          { return parser.LE_OP;
          }
        case 86: break;
        case 14: 
          { return parser.NE_OP;
          }
        case 87: break;
        case 19: 
          { return parser.TO;
          }
        case 88: break;
        case 30: 
          { yyparser.yylval = new upbeatVal(0);
// TODO: implement attributes for REST constant lexeme
			yyparser.yylval.type = upbeatVal.Type.ubPHRASE;
			return parser.CONSTANT;
          }
        case 89: break;
        case 9: 
          { return parser.LESS_OP;
          }
        case 90: break;
        case 36: 
          { if (yyparser.yydebug) {
				System.out.print("Found a TEMPO\n");
			}
			return parser.TEMPO;
          }
        case 91: break;
        case 50: 
          { if (yyparser.yydebug) {
				System.out.print("Found a TIME_SIGNATURE\n");
			}
			yyparser.yylval = new upbeatVal(4.0);
			return parser.TIME_SIGNATURE;
          }
        case 92: break;
        case 12: 
          { return parser.EQ_OP;
          }
        case 93: break;
        case 22: 
          { /* comment */
          }
        case 94: break;
        case 13: 
          { return parser.DB;
          }
        case 95: break;
        case 48: 
          { return parser.INSTRUMENT;
          }
        case 96: break;
        case 11: 
          { yyparser.yylval = new upbeatVal(yytext().substring(1, yytext().lengt
h()-1));
			yyparser.yylval.sval = yytext().substring(0);
			if (yyparser.yydebug) {
				System.out.printf("Got a string! %s\n", yytext()
);
			}
			yyparser.yylval.type = upbeatVal.Type.ubSTRING;
			return parser.STRING_LITERAL;
          }
        case 97: break;
        case 4: 
          { int theint = Integer.parseInt(yytext());
		  yyparser.yylval = new upbeatVal(theint);
		  yyparser.yylval.code = "" + theint;
		  yyparser.yylval.type = upbeatVal.Type.ubINT;
			return parser.CONSTANT;
          }
        case 98: break;
        case 41: 
          { return parser.REPEAT;
          }
        case 99: break;
        case 24: 
          { String numpart = yytext().substring(2);
			yyparser.yylval = new upbeatVal(Integer.parseInt(numpart
));
			yyparser.yylval.code = numpart;
			yyparser.yylval.type = upbeatVal.Type.ubTIME;
			return parser.CONSTANT;
          }
        case 100: break;
        default: 
          if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
            zzAtEOF = true;
            zzDoEOF();
              { return 0; }
          } 
          else {
            zzScanError(ZZ_NO_MATCH);
          }
      }
    }
  }


}




Filename: Frontend//tests/Test1.up
Author: Matt
TIME_SIGNATURE 4/4;
TEMPO 120;

// This test is designed to test Conductor member functions
// It also does some testing of scope

Conductor {
	int i = 0;
	int j = 0;
	
	TestFunc1() {
		Return;
	}
	
	int TestFunc2() {
		Return i + j;
	}
	
	float TestFunc3() {
		float k = 0.0;
		Return k;
	}
	
	bool TestFunc4( bool b ) {
		Return b;
	}
	
	cue TestFunc5( int x, int y ) {
		cue myCue = "Blah";
		myCue.data = x + y;
		Return myCue;
	}
	
	TestFunc6( int x, float y ) {
		i = x;
		j = y;
	}
	
	// Testing recursion with fibonacci numbers!
	int Fib( int n ) {
		Case{
			(n == 0) Return 1;
			(n == 1) Return 1;
		}
		Return Fib( n - 1 ) + Fib( n - 2 );
	}
	
	TestFunc7( int x, float y ) {
		TestFunc6( j, y );
	}
	
	cue TestFunc8( int x, int y ) {
		Return TestFunc5( x, y );
	}
	
	Conduct( time currentMeasure ) {
		int tempInt;
		float tempFloat;
		
		// Apparently this is allowed.  Do we want this?
		;
		
		TestFunc1();
		TestFunc2();
		tempInt = TestFunc2();
		tempFloat = TestFunc3();
		
		Case{ (TestFunc4(TRUE)) TestFunc4(FALSE); }
		
		Case {
			(TRUE) {
				int tempCaseInt = tempInt;
				tempInt = tempInt + 1;
			}
		}
		
		TestFunc6( tempInt, i );
		tempInt = Fib( 10 );
		TestFunc7(Fib(15), tempFloat);
		tempInt = TestFunc8(tempInt, j).data;	
	}
}

Musician "Test1_Musician" {
	phrase temp = "Blah.mid";
	
	"Blah" {
		//don't do anything!
	}
}



Filename: Frontend//tests/Test2.up
Author: Matt
TIME_SIGNATURE 4/4;
TEMPO 120;

// This will test Case and Repeat statements

Conductor {
	bool TestFunc() {
		Return TRUE;
	}
	
	Conduct( time currentMeasure ) {
		int tempInt1;
		int tempInt2 = 2;
		int tempInt3 = 0;
		bool t = TRUE;
		bool f = FALSE;
		float tempFloat = 1.0;
		time tempTime = @m1;
		
		Repeat( 10 ) {
			tempInt2 = tempInt2 + 1;
			Case{ (tempInt2 < 5) tempInt3 = tempInt3 + tempInt2; }
		}
		
		Repeat( tempFloat ) {
			tempInt2 = tempInt2 + 1;
		}
		
		Repeat( (int)tempFloat ) {
			tempInt2 = tempInt2 + 1;
		}
		
		Repeat( tempTime ) {
			tempInt2 = tempInt2 + 1;
		}
		
		Repeat( (int)tempTime ) {
			tempInt2 = tempInt2 + 1;
		}
		
		Repeat( tempInt2 ) {
			tempInt2 = tempInt2 + 1;
		}
		
		tempInt1 = 0;
		Repeat( f ) {
			tempInt3 = tempInt3 + tempInt2 + tempInt1;
			Case{ (tempInt3 == tempInt2) f = FALSE; }
		}
		
		Repeat( t ) {
			Case{ (tempInt3 < tempInt2) t = FALSE; }
			tempInt2 = tempInt2 - 1;
		}
		
		Case {
			(tempInt2 < 0) Return;
			(tempInt2 < 100){
				tempInt1 = tempInt1 + tempInt3;
				Repeat( tempInt1 ) {
					tempInt2 = tempInt2 + tempInt1;
				}
			}
			(FALSE) Return;
			(TRUE) Return;
		}
		
		Case( t ) {
			tempInt2 = tempInt2 + tempInt1;
		}
		
		Case( TestFunc() )
			tempInt2 = tempInt2 + tempInt1;
	}
}

Musician "Test2_Musician" {
	phrase blah = "blah.mid";
	
	"Blah" {
		// Don't do anything for now!
	}
}



Filename: Frontend//tests/Test3.up
Author: Matt
// This will test Boolean expressions

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	int i;
	i = 0;
	Conduct( time currentMeasure ) {
		bool t = TRUE;
		bool f = FALSE;
		bool tempBool = TRUE;
		cue tempCue1 = "Ooga";
		cue tempCue2 = "Booga";
		int tempInt1 = 0;
		int tempInt2 = 0;
		float tempFloat1 = 0.0;
		float tempFloat2 = 0.0;
		time tempTime1 = 1;
		time tempTime2 = -1;
		
		// Testing or
		tempBool = t or f;
		tempBool = TRUE or f;
		tempBool = (t or f) or (TRUE or FALSE);
		
		// Testing and
		tempBool = t and f;
		tempBool = TRUE and TRUE;
		tempBool = (t and f) or (TRUE and f) and t;
		
		// Testing the precedence of or and and
		tempBool = t or f and f and f or f == f;
		
		// Testing relops
		tempBool = tempInt1 == tempInt2;
		tempBool = tempFloat1 == tempFloat2;
		tempBool = tempTime1 == tempInt1;
		tempBool = tempInt1 == tempTime1;
		tempBool = t == f;
		tempBool = tempCue1 == tempCue2;
		tempBool = tempTime1 == tempTime2;
		
		tempBool = t == f == tempBool == f == t;
		
		tempBool = tempInt1 != tempInt2;
		tempBool = tempFloat1 != tempFloat2;
		tempBool = tempTime1 != tempInt1;
		tempBool = tempInt1 != tempTime1;
		tempBool = t != f;
		tempBool = tempCue1 != tempCue2;
		tempBool = tempTime1 != tempTime2;
		
		tempBool = t != f != tempBool != f != t;
		
		tempBool = tempInt1 <= tempInt2;
		tempBool = tempInt1 <= tempFloat1;
		tempBool = tempFloat1 <= tempInt1;
		tempBool = tempFloat1 <= tempFloat2;
		tempBool = tempTime1 <= tempInt1;
		tempBool = tempInt1 <= tempTime1;
		tempBool = tempTime1 <= tempTime2;
		
		tempBool = tempInt1 < tempInt2;
		tempBool = tempInt1 < tempFloat1;
		tempBool = tempFloat1 < tempInt1;
		tempBool = tempFloat1 < tempFloat2;
		tempBool = tempTime1 < tempInt1;
		tempBool = tempInt1 < tempTime1;
		tempBool = tempTime1 < tempTime2;
		
		tempBool = tempInt1 >= tempInt2;
		tempBool = tempInt1 >= tempFloat1;
		tempBool = tempFloat1 >= tempInt1;
		tempBool = tempFloat1 >= tempFloat2;
		tempBool = tempTime1 >= tempInt1;
		tempBool = tempInt1 >= tempTime1;
		tempBool = tempTime1 >= tempTime2;
		
		tempBool = tempInt1 > tempInt2;
		tempBool = tempInt1 > tempFloat1;
		tempBool = tempFloat1 > tempInt1;
		tempBool = tempFloat1 > tempFloat2;
		tempBool = tempTime1 > tempInt1;
		tempBool = tempInt1 > tempTime1;
		tempBool = tempTime1 > tempTime2;
		
		tempBool = !tempBool;
		tempBool = !(t == f or !t and !f);
		
		// Now for the range expression
		tempBool = 1.0 in (0, 10.0);
		tempBool = tempFloat1 in [0.0, 10);
		tempBool = 7 in (0, 10];
		tempBool = tempInt1 in [0, 10];
		tempBool = !(tempInt2 in (tempInt1, tempInt2));
	}
}

Musician "Test3_Musician" {
	phrase blah = "blah.mid";
	
	"Blah" {
		// Don't do anything for now!
	}
}



Filename: Frontend//tests/Test4.up
Author: Matt
// This is a test for arithmetic expressions

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	Conduct( time currentMeasure ) {
		bool t = TRUE;
		bool f = FALSE;
		bool tempBool = TRUE;
		cue tempCue1 = "Ooga";
		cue tempCue2 = "Booga";
		int tempInt1 = 0;
		int tempInt2 = 0;
		float tempFloat1 = 0.0;
		float tempFloat2 = 0.0;
		time tempTime1 = @m2;
		time tempTime2 = @m156565;
		
		// Testing +
		tempInt1 = tempInt1 + tempInt2;
		tempFloat1 = tempInt1 + tempFloat1;
		tempFloat1 = tempFloat1 + tempInt1;
		tempFloat1 = tempFloat1 + tempFloat2;
		tempTime1 = tempInt1 + tempTime1;
		tempTime1 = tempTime1 + tempInt1;
		tempTime1 = tempTime1 + tempTime2;
		
		tempCue1 = "Ooga" + "Booga";
		tempCue1 = "Ooga" + tempInt1;
		tempCue1 = tempInt1 + "Booga";
		
		// Testing -
		tempInt1 = tempInt1 - tempInt2;
		tempFloat1 = tempInt1 - tempFloat1;
		tempFloat1 = tempFloat1 - tempInt1;
		tempFloat1 = tempFloat1 - tempFloat2;
		tempTime1 = tempInt1 - tempTime1;
		tempTime1 = tempTime1 - tempInt1;
		tempTime1 = tempTime1 - tempTime2;
		
		// Testing *
		tempInt1 = tempInt1 * tempInt2;
		tempFloat1 = tempInt1 * tempFloat1;
		tempFloat1 = tempFloat1 * tempInt1;
		tempFloat1 = tempFloat1 * tempFloat2;
		tempTime1 = tempInt1 * tempTime1;
		tempTime1 = tempTime1 * tempInt1;
		tempTime1 = tempTime1 * tempTime2;
		
		// Testing /
		tempInt1 = tempInt1 / tempInt2;
		tempFloat1 = tempInt1 / tempFloat1;
		tempFloat1 = tempFloat1 / tempInt1;
		tempFloat1 = tempFloat1 / tempFloat2;
		tempTime1 = tempInt1 / tempTime1;
		tempTime1 = tempTime1 / tempInt1;
		tempTime1 = tempTime1 / tempTime2;
		
		// Testing %
		tempInt1 = tempInt1 % tempInt2;
		tempTime1 = tempInt1 % tempTime1;
		tempTime1 = tempTime1 % tempInt1;
		tempTime1 = tempTime1 % tempTime2;
		
		// Testing the precedence of the operators
		tempInt1 = 3 % 1 / 2 + 2 + 3 - 4 * 5;
		
		// Testing unary + and -
		tempInt1 = -tempInt1;
		tempInt1 = +tempInt1;
		tempFloat1 = -tempFloat1;
		tempFloat1 = +tempFloat1;
		tempTime1 = -tempTime1;
		tempTime1 = +tempTime1;
		
		// Testing precedence with unary ops as well!
		tempInt1 = 3 % -1 + +2 / 17 * 123 + 34 + -1 - +434;
	}
}

Musician "Test4_Musician" {
	phrase blah = "blah.mid";
	
	"Blah" {
		// Don't do anything for now!
	}
}



Filename: Frontend//tests/Test5.up
Author: Matt
// This is a test for assignments and casts

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{

	TestFuncInt( int a ) {
	}
	
	TestFuncFloat( float a ) {
	}
	
	TestFuncTime( time a ) {
	}
	
	int TestFuncRetInt() {
		Return 1;
	}
	
	float TestFuncRetFloat() {
		Return 1.0;
	}
	
	time TestFuncRetTime() {
		Return @m1;
	}
	
	int TestFuncRetCastInt() {
		Return 1.0;
	}
	
	float TestFuncRetCastFloat() {
		Return 1;
	}
	
	time TestFuncRetCastTime() {
		Return 17.0;
	}

	Conduct( time currentMeasure ) {
		bool t = TRUE;
		bool f = t;
		bool tempBool = TRUE;
		cue tempCue1 = "Ooga";
		cue tempCue2 = tempCue1;
		int tempInt1 = 0;
		int tempInt2 = tempInt1;
		float tempFloat1 = 0.0;
		float tempFloat2 = tempFloat1;
		time tempTime1 = @m1;
		time tempTime2 = tempTime1;
		
		// This tests assignments
		t = f;
		tempCue1 = tempCue2;
		tempInt1 = tempInt2;
		tempFloat1 = tempFloat2;
		tempTime1 = tempTime2;
		tempInt1 = tempFloat1;
		tempFloat1 = tempInt1;
		tempFloat1 = tempTime1;
		tempTime1 = tempFloat1;
		tempInt1 = tempTime1;
		tempTime1 = tempInt1;
		
		// This tests casts
		tempInt1 = (int)tempInt2;
		tempFloat1 = (float)tempFloat2;
		t = (bool)f;
		tempCue1 = (cue)tempCue2;
		tempTime1 = (time)tempTime2;
		tempFloat1 = (float)tempInt1;
		tempFloat1 = (float)tempTime1;
		tempInt1 = (int)tempFloat1;
		tempInt1 = (int)tempTime1;
		tempTime1 = (time)tempInt1;
		tempTime1 = (time)tempFloat1;
		
		TestFuncInt(tempInt1);
		TestFuncInt(tempFloat1);
		TestFuncInt(tempTime1);
		
		TestFuncFloat(tempInt1);
		TestFuncFloat(tempFloat1);
		TestFuncFloat(tempTime1);
		
		TestFuncTime(tempInt1);
		TestFuncTime(tempFloat1);
		TestFuncTime(tempTime1);
	}
}

Musician "Test5_Musician" {
	phrase blah = "blah.mid";
	
	"Blah" {
		// Don't do anything for now!
	}
}



Filename: Frontend//tests/Test6.up
Author: Matt
// This is a test for input expressions and adding cues

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	float sum = 0;
	
	float TestFunc() {
		Return input.currentValue;
	}
	
	float TestFunc2( int at ) {
		Return input.valueAt(at);
	}
	
	bool TestFunc3() {
		Return input.more;
	}
	
	time TestFunc4() {
		Return @m1;
	}
	
	cue TestFunc5() {
		cue myCue = "Ooga";
		Return myCue;
	}
	
	Conduct( time currentMeasure ) {
		cue tempCue1 = "Ooga";
		cue tempCue2 = "Booga";
		int i = input.currentValue;
		int j = input.valueAt( currentMeasure - 1 );
		
		sum = sum + input.currentValue;
		
		Case {
			(input.more) i = input.currentValue;
			(!input.more) j = input.valueAt(i);
		}
		
		Add tempCue1 currentMeasure;
		Add tempCue1 TestFunc();
		Add tempCue1 @m2;
		Add tempCue1 TestFunc4();
		Add TestFunc5() TestFunc4();
		Add tempCue1 @m2 + @m3 + 1232;
		Add tempCue1 1.0;
	}
}

Musician "Test6_Musician" {
	phrase blah = "blah.mid";
	
	"Blah" {
		// Don't do anything for now!
	}
}



Filename: Frontend//tests/Test7.up
Author: Matt
// This is a test for multiple Musicians with stuff in their constructors

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	Conduct( time currentMeasure ) {
	}
}

Musician "Test7_Musician_1" {
	phrase p1 = "Blah.mid";
	
	"Cue One" {
		p1 = "OtherBlah.mid";
	}
	"Cue Two" {
	}
}

Musician "Test7_Musician_2" {
	phrase p1;
	int i;
	p1 = "Blah.mid";
	
	"Cue One" {
		i = 0;
	}
	"Cue Two" {
	}
	"Cue Three" {
	}
}

Musician "Test7_Musician_3" {
	phrase p1;
	
	"Cue One" {
		p1 = "Blah.mid";
	}
	"Cue Two" {
		p1 = "Blah.mid";
	}
	"Cue Three" {
		p1 = "Blah.mid";
	}
}



Filename: Frontend//tests/Test8.up
Author: Matt
// This is a test play statements

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	Conduct( time currentMeasure ) {
	}
}

Musician "Test8_Musician" {
	phrase p1 = "Blah.mid";
	phrase p2 = "Blah2.mid";
	phrase p3 = "Blah3.mid";
	
	"Cue One" {
		|| p1 ||;
		|| REST ||;
		|| p1 ||;
		|| p1 | p2 | p3 || p1 | REST ||;
	}
	"Cue Two" {
		||: p1 :||2: p2 | p3 :||4;
		|| p1 | REST ||: p3 :||2: p2 :||;
	}
}



Filename: Frontend//tests/Test9.up
Author: Matt
// This is a test for music parameter (i.e. pitch, volume, etc. ) changes
// It also tests the $ keyword

TIME_SIGNATURE 4/4;
TEMPO 120;

Conductor{
	Conduct( time currentMeasure ) {
	}
}

Musician "Test9_Musician_1" {
	phrase p1 = "Blah.mid";
	phrase p2 = "Blah2.mid";
	phrase p3 = "Blah3.mid";
	
	"Cue One" {
		int i = $.data;
		float j = $.data;
		
		Case{
			($.data in (0, 10))
				Change Volume by $.data;
			($.data < 20)
				||p1||;
		}
		
		Change Instrument to $.data;
		Change Instrument by $.data;
		Change Volume to $.data;
		Change Volume by $.data;
		Change Pitch to $.data;
		Change Pitch by $.data;
		
		Change Instrument to 1.0;
		Change Instrument by 1.0;
		Change Volume to 1.0;
		Change Volume by 1.0;
		Change Pitch to 1.0;
		Change Pitch by 1.0;
		
		||: p1 | p2 | p3 :||;
	}
	"Cue Two" {
		||: p1 | p2 | p3 :||;
	}
}

Musician "Test9_Musician_2" {
	phrase p1 = "Blah.mid";
	phrase p2 = "Blah2.mid";
	phrase p3 = "Blah3.mid";
	
	Change Volume by 1;
	Change Pitch by 1;
	Change Instrument to 1;
	
	"Cue One" {
	}
	"Cue Two" {
	}
}

Musician "Test9_Musician_3" {
	Change Volume to 1;
	Change Pitch by 1;
	
	"Cue One" {
		phrase p1 = "Blah.mid";
		||:p1:||;
	}
	"Cue Two" {
		phrase p2 = "Blah2.mid";
		||:p2:||;
	}
}




